Search code examples
haskellghcnewtypetype-variables

What is the rule of the order of multiple type variables in haskell?


For example, ParsecT has multiple type variables in its definition.

newtype ParsecT s u m a
    = ParsecT {unParser :: forall b .
                 State s u
              -> (a -> State s u -> ParseError -> m b) 
              -> (ParseError -> m b)                   
              -> (a -> State s u -> ParseError -> m b) 
              -> (ParseError -> m b)                   
              -> m b
             } 

Can we do it like this ?

newtype ParsecT m a s u     -- Only the order of s u m a is changed to m a s u.
    = ParsecT {unParser :: forall b .
                 State s u
              -> (a -> State s u -> ParseError -> m b) 
              -> (ParseError -> m b)                   
              -> (a -> State s u -> ParseError -> m b) 
              -> (ParseError -> m b)                   
              -> m b
             }

I am wondering whether there is a rule or principle about the order of type variables when we define a newtype.


Solution

  • In this case, a is last because we want ParsecT s u m __ to be a monad, that way, what our parsers look for can depend on what they found before, and so forth. If u came last we couldn't write

     instance Monad m => Monad (ParsecT s u m) where ...
    

    m is next-to-last because we want ParsecT s u to be a 'monad transformer'

     class MonadTrans t where 
         lift :: m a -> t m a 
    
     instance MonadTrans (ParsecT s u) where ...
    

    If we put the m first, this instance wouldn't be possible. There doesn't seem to be any similar reason for the ordering of s and u.