## GHC 8.0.1 errors from Writer and State monads

Question

I'm relatively new to Haskell and trying to port the UNIX wc program demonstrated in Kernighan and Ritchie using monadic composition, as shown in *The Essence of the Iterator Pattern* by Jeremy Gibbons and Bruno C. d. S. Oliveira, and having some trouble getting it to compile. Here's my code:

```
import Control.Monad.Writer
import Control.Monad.State
import Data.Char
test :: Bool -> Integer
test b = if b then 1 else 0
ccmBody :: Char -> Writer Integer Char
ccmBody c = do
tell 1
return c
ccm :: String -> Writer Integer String
ccm = mapM ccmBody
lcmBody :: Char -> Writer Integer Char
lcmBody c = do
tell(test(c == '\n'))
return c
lcm' :: String -> Writer Integer String
lcm' = mapM lcmBody
wcmBody :: Char -> State (Integer, Bool) Char
wcmBody c = let s = not (isSpace c) in do
(n,w) <- get
put (n + test(not (w || s)), s)
return c
wcm :: String -> State (Integer, Bool) String
wcm = mapM wcmBody
clwcm = ccm >=> lcm' >=> wcm
```

And the compiler errors:

```
wordcount.hs:10:3: error: …
• No instance for (Monoid Integer) arising from a do statement
• In a stmt of a 'do' block: tell 1
In the expression:
do { tell 1;
return c }
In an equation for ‘ccmBody’:
ccmBody c
= do { tell 1;
return c }
wordcount.hs:33:26: error: …
• Couldn't match type ‘StateT
(Integer, Bool) Data.Functor.Identity.Identity’
with ‘WriterT Integer Data.Functor.Identity.Identity’
Expected type: String
-> WriterT Integer Data.Functor.Identity.Identity String
Actual type: String -> State (Integer, Bool) String
• In the second argument of ‘(>=>)’, namely ‘wcm’
In the second argument of ‘(>=>)’, namely ‘lcm' >=> wcm’
In the expression: ccm >=> lcm' >=> wcm
Compilation failed.
```

I can't understand what I'm doing wrong here in either case. Any help would be greatly appreciated. Thanks!

Show source

## Answers ( 1 )

For the

`Writer`

monad to work, the object you're writing has to be an instance of`Monoid`

.`tell`

uses`mappend`

to add its argument to the running log.For integers, however, there are at least two good choices for a

`Monoid`

instance. One of them is addition, with 0 as the unit element:and the other is multiplication with 1:

How should the Haskell designers choose between these two options? They're both equally valid, and both useful in different situations. In the end they decided not to express an opinion, leaving

`Int`

without a`Monoid`

instance of its own and instead providing two`newtype`

s to allow you to choose which instance you want.These two

`newtype`

s are found in the`Data.Monoid`

module. I'm guessing in your case you want to add up the numbers in the`Writer`

monad, so all you should need to do is change all your type signatures from`Writer Integer`

to`Writer (Sum Integer)`

.The other type error is GHC telling you that you can't compose a

`Writer`

action with a`State`

action. You have`wcm :: State (Integer, Bool) String`

and`ccm :: Writer Integer String`

. Skim-reading your code, it looks like you're only using the`Integer`

component of your state to add things up (I'm guessing it's meant to take part in the running total along with the`Writer`

bits?), so I would consider using themonad transformerversion of`State`

:and then using

`lift`

to bring the plain old`Writer Integer`

monads into the`StateT`

-enriched context.If you're not used to monad transformers yet, the other option is to write everything in the

`State (Integer, Bool)`

monad.