Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to compile Writer Monad example from "Learn you a Haskell"

Tags:

haskell

monads

The following code, which is verbatim from LYAH, doesn't compile. Code and compile-time error are included below. On the LYAH page, the code is ~15% down the page, yay emacs browser :)

Any ideas why? Am I overlooking something totally obvious?

(Despite the similarity in post-titles, I think my question is different from this one.)


Here's the code (in a file which I named testcopy.hs)

import Control.Monad.Writer

logNumber :: Int -> Writer [String] Int
logNumber x = Writer (x, ["Got number: " ++ show x])

multWithLog :: Writer [String] Int
multWithLog = do
    a <- logNumber 3
    b <- logNumber 5
    return (a*b)

And here's the compile-time error:

Prelude> :l testcopy.hs
[1 of 1] Compiling Main             ( testcopy.hs, interpreted )
testcopy.hs:4:15:
    Not in scope: data constructor `Writer'
    Perhaps you meant `WriterT' (imported from Control.Monad.Writer)
Failed, modules loaded: none.
like image 879
iceman Avatar asked Oct 16 '14 22:10

iceman


2 Answers

LYAH is outdated in this example. You should use the writer smart constructor method instead of the (now non-existent) Writer data constructor.

To expand a bit, these data types were updated to be more compatible with monad transformers. As a result, there is a general WriterT, for use in a monad transformer stack, and a Writer type synonym that composes WriterT with Identity. Because of this, there is no longer a data constructor associated specifically with the Writer type (since Writer is a type synonym).

Luckily, despite this complication, the solution is pretty simple: replace Writer with writer.

like image 168
David Young Avatar answered Oct 03 '22 00:10

David Young


The correct version in GHC 7.10.3 should be like this

import Control.Monad.Writer

logNumber :: Int -> Writer [String] Int
logNumber x = writer (x, ["Got number: " ++ show x])

multWithLog :: Writer [String] Int
multWithLog = do
    a <- logNumber 3
    b <- logNumber 5
    return (a*b)
like image 42
wshcdr Avatar answered Oct 02 '22 23:10

wshcdr