haskellmonadswritertype-signature

Haskell MonadWriter type signature


Noob question on MonadWriter:

monadWrite :: Writer String Int
monadWrite = writer (3003, "log 1\n") 

Why is it that String comes first in the typesig and Int second, while 3003 is clearly an Int while "log 1\n" is a String. Trivial I know, but I would like to understand.


Solution

  • There is no particular reason to put the result (3003) first and the output ("log 1\n") second in the argument to writer. The order was, I suppose, chosen to correspond to the internal representation of WriterT:

    newtype WriterT w m a = WriterT { runWriterT :: m (a, w) }
    

    (for Writer, m is identity).

    However, in the type signature for Writer, the order of arguments matters. If we look at, for example, the Functor typeclass with a member

    fmap :: (a -> b) -> f a -> f b
    

    it makes it possible to substitute Writer String (or generally, Writer result) for f and obtain

    fmap :: (a -> b) -> Writer result a -> Writer result b
    

    which is exactly the correct order of arguments. Swapping them would make implementing Functor impossible (without some trickery).

    This is true for all types/functions which take more than one parameter: the only way they can be used as one-argument types/functions is by varying the last argument, not the other ones.

    See related questions discussing similar issues:

    Switch order of arguments for instance declaration in Haskell

    Currying out of order in Haskell