11

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.

Znatz
  • 1,530
  • 2
  • 18
  • 31
  • A similar question at the value level is here: http://stackoverflow.com/questions/5863128/ordering-of-parameters-to-make-use-of-currying – cheecheeo May 31 '13 at 16:34

1 Answers1

16

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.

applicative
  • 8,081
  • 35
  • 38
  • 1
    Worth bringing up that `newtype` is sometimes used purely to manipulate the order of the type indices so that you can provide instances for `Functor` and `Monad` on multiple typed holes. – J. Abrahamson Jun 01 '13 at 01:57
  • @applicative, thank you. I see now. I've tried but it is actually impossible to alter the order and preserve the original class-instance structure. – Znatz Jun 03 '13 at 13:38