Search code examples
haskellnewtype

Haskell newtype syntax


Please help me to understand the following definition:

newtype Writer w a = Writer { runWriter :: (a,w) } 

instance (Monoid w) => Monad (Writer w) where 
    return a             = Writer (a,mempty) 
    (Writer (a,w)) >>= f = let (a',w') = runWriter $ f a in Writer (a',w `mappend` w')

Why is runWriter is declared as

runWriter :: (a,w)

when its actual type is:

runWriter :: Writer w a -> (a, w)

Once I tried with ghci I realized this must be some implicit argument since type "a" has to be determined, but what is exactly happening here?


Solution

  • Because runWriter is a record field accessor on Writer. It's actually almost equivalent to

    runWriter (Writer x) = x
    

    Haskell just has records to give

    1. More convient syntax since this sort of accessor code is quite common
    2. The ability for functional updates
    3. A few other extensions

    eg

    someWriter{runWriter = (new, values)} -- Returns a new Writer.
    

    If it helps, think of it as something like a "functional getter" in the roughest sense. This might not seem terribly important with 1 field, you can always pattern match, but when you have 5 fields, records + functional updates are super helpful. See LYAH for a more in depth explanation.