
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