
On Sat, Dec 13, 2008 at 3:00 PM, Andrew Coppin
So how is foo :: ((forall b. a -> m b) -> m a) -> m a different from bar :: forall b. ((a -> m b) -> m a) -> m a
Lets use a simpler example:
foo :: (forall a. a -> a) -> (Int, String) bar :: forall a. (a -> a) -> (Int, String)
-- this compiles foo f = (f 1, f "hello")
-- this does not compile -- bar f = (f 1, f "hello")
-- but this does bar f = (1, "hello")
The difference is that the *caller* of bar chooses how to instantiate a, whereas the caller of foo must pass in a polymorphic function that foo can instantiate at whatever type it wants... even multiple different types!
ident x = x plus1 x = x + 1 :: Int
-- legal useFoo = foo ident -- not legal, not polymorphic -- useFoo = foo plus1
-- legal useBar = bar ident -- also legal, instantiate "a" in the type of "bar" with "Int" useBar2 = bar plus1
-- ryan