haskellmonadsmonad-transformers

Monad Transformer missing parameter (?)


I've got this type alias:

type Board a = ReaderT String (StateT String IO) a

I know that StateT has the kind * -> (* -> *) -> * -> * so it should get three parameters. But in the above example, StateT only receives String and the IO-Monad. Now I'm wondering where the missing parameter is passed to StateT.

Same goes for IO which should get one parameter but doesn't get any.


Solution

  • If you look at the definition of ReaderT, you will see that its second parameter is itself applied to its last parameter:

    newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }
                                                         ^^^
                                                      right here
    

    Which means that its second parameter m must have kind m :: * -> *. And this is exactly what you get if you apply only two, not three, parameters to StateT:

    StateT :: * -> (* -> *) -> * -> *
    StateT x y :: * -> *
    (where x :: * and y :: * -> *)
    

    When substituting the definition of ReaderT in your type Board, you'll get:

    (1) type Board a = ReaderT String (StateT String IO) a
    
    -- Substituting ReaderT definition (pseudocode)
    (2) type Board a = { runReaderT :: String -> StateT String IO a }
                                                 ^^^^^^^^^^^^^^^^^^
                                    Look, StateT has all its three parameters!