
What is the difference between forall as in: runSThttp://www.haskell.org/ghc/docs/6.10-latest/html/libraries/base/Control-Mona...:: ( forall s. SThttp://www.haskell.org/ghc/docs/6.10-latest/html/libraries/base/Control-Mona...s a) -> a and the "=>" as in evalStateThttp://www.haskell.org/ghc/docs/6.6/html/libraries/mtl/Control-Monad-State.h...:: Monadhttp://www.haskell.org/ghc/docs/6.6/html/libraries/base/Control-Monad.html#t...m => StateThttp://www.haskell.org/ghc/docs/6.6/html/libraries/mtl/Control-Monad-State.h...s m a -> s -> m a thanks daryoush

Daryoush Mehrtash wrote:
What is the difference between forall as in:
runST :: (forall s. ST s a) -> a
and the "=>" as in
evalStateT :: Monad m => StateT s m a -> s -> m a
The forall is Rank-2 polymorphism (the argument must be polymorphic in s). The => is for typeclass constraints (restricting the Rank-1 polymorphism on m, but not so far as to make it monomorphic). Or did you have another question in mind? -- Live well, ~wren

Hello Daryoush, Wednesday, May 13, 2009, 6:11:10 AM, you wrote:
runST :: (forall s. ST s a) -> a
evalStateT :: Monad m => StateT s m a -> s -> m a
these are quite opposite things. later means that you should pass some value of Monad class (well, in this case it's StateT value whose type is limited to Monad in second argument) first means that you should pass *polymorphic* value - i.e. value valid for *any* s thta's even more exiting is that evalStateT is example of polymorphic value - it's a function that can process any Monad value but definitely it will be easier to start with simpler examples. let's see: length :: forall a. [a] -> Int it's, like evalStateT, polymorphic function - it can process lists of any type. more specific polymorphic functions may have class constraints: sum :: (forall a. Num a) => [a] -> a that may be reduced down to: sum :: (Num a) => [a] -> a now let's write a function that may accept *any* function with the type as length: rank2_function :: (forall a. [a] -> Int) -> Int -> Int rank2_function f 1 = f "test" rank2_function f 2 = f [1..3] -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

2009/05/12 Daryoush Mehrtash
runST :: (forall s. ST s a) -> a
The `forall` here has a rather elaborate purpose.
evalStateT :: Monad m => StateT s m a -> s -> m a
"Where `m` is in `Monad`, we have... Let's put in the "hidden `forall`": evalStateT :: forall s m a. (Monad m) => StateT s m a -> s -> m a The `(Monad m)` is our "class context" -- it tells us that `m` must have an implementation for `Monad`. The `forall` is simple quantification (type signatures are implicitly universally quantified). Looking at your first example, let's put in the hidden `forall`: runST :: forall a. (forall s. ST s a) -> a This is a little fancy. It tells us that for a given `a`, `runST` must accept a stateful computation with a state of any type whatsoever; hence we can not return the type of the state as the result of the computation. My explanation makes short work of an interesting topic; using class contexts is quite a bit more common than using tricky `forall`s. The important thing to seed is that the `=>` introduces a class constraint/condition on our type signature. You can imagine that it is always there: id :: forall a. () => a -> a You can read `=>` as "entails". Then `() =>` is "the universe entails..." and `(Monad m) =>` is "the universe with `m` in `Monad` entails..." -- Jason Dusek
participants (4)
-
Bulat Ziganshin
-
Daryoush Mehrtash
-
Jason Dusek
-
wren ng thornton