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?
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
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.