On Sat, Dec 13, 2008 at 3:00 PM, Andrew Coppin <andrewcop...@btinternet.com> wrote: > 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 _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe