Difference between revisions of "DDC/PolymorphicUpdate"

From HaskellWiki
< DDC
Jump to navigation Jump to search
Line 3: Line 3:
   
 
<haskell>
 
<haskell>
makeGetSet :: a -> (() -> a, a -> ())
+
makeGetSet :: forall a. a -> (() -> a, a -> ())
 
makeGetSet x
 
makeGetSet x
 
= do box = Just x
 
= do box = Just x
Line 24: Line 24:
 
out $ fst getSet () -- prints '23'
 
out $ fst getSet () -- prints '23'
 
</haskell>
 
</haskell>
  +
  +
The trouble comes when we create a box containing value of polymorphic type. Without closure typing we could define:
  +
  +
<haskell>
  +
...
  +
getSet2 :: forall a. (() -> [a], [a] -> ())
  +
getSet2 = makeGetSet []
  +
</haskell>
  +
  +
As the list is empty, we can treat it as being of any type <hask>(forall a. [a])</hask>, but suppose we update it at two different types...
  +
  +
<haskell>
  +
snd getSet2 [23]
  +
snd getSet2 ["trouble"]
  +
  +
out $ fst getSet2 ()
  +
</haskell>
  +
  +
The type of <hask>getSet2</hask> has <hask>forall a.</hask> at the front, so there is nothing to stop us from calling the set function at both <hask>[Int]</hask> and <hask>[String]</hask>, but what should the type be when use the get function in the last line?

Revision as of 06:38, 19 March 2008

Get/Set

Consider the following function:

makeGetSet :: forall a. a -> (() -> a, a -> ())
makeGetSet x
 = do 	box	= Just x
	get ()	= case box of { Just z -> z; }
	set z	= box#x #= z
	(get, set)

This function allocates a box which can store a value and returns a tuple of functions which can be used to get and set that value.

As the function is polymorphic, we can create boxes of whatever type we would like:

main ()
 = do	getSet	= makeGetSet 5

 	out $ fst getSet ()   -- prints '5'

	snd getSet 23         -- update the box
	out $ fst getSet ()   -- prints '23'

The trouble comes when we create a box containing value of polymorphic type. Without closure typing we could define:

        ...
        getSet2 :: forall a. (() -> [a], [a] -> ())
        getSet2 = makeGetSet []

As the list is empty, we can treat it as being of any type (forall a. [a]), but suppose we update it at two different types...

       snd getSet2 [23]
       snd getSet2 ["trouble"]

       out $ fst getSet2 ()

The type of getSet2 has forall a. at the front, so there is nothing to stop us from calling the set function at both [Int] and [String], but what should the type be when use the get function in the last line?