Difference between revisions of "DDC/PolymorphicUpdate"
< DDC
Jump to navigation
Jump to search
Line 44: | Line 44: | ||
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? |
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? |
||
+ | |||
+ | == Dangerous type variables == |
Revision as of 06:42, 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 to get and set that value.
As the function is polymorphic, we can create boxes of whatever type we would like:
main ()
= do getSet :: (() -> Int, Int -> ())
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 a 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?