[Haskell-cafe] forall vs "=>"

Jason Dusek jason.dusek at gmail.com
Wed May 13 23:45:54 EDT 2009

2009/05/12 Daryoush Mehrtash <dmehrtash at gmail.com>:
> 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

More information about the Haskell-Cafe mailing list