2014-10-16 3 views
8

Il seguente codice, che è verbatim from LYAH, non viene compilato. Codice e errore di compilazione sono inclusi di seguito. Nella pagina LYAH, il codice è ~ 15% in fondo alla pagina, yay emacs browser :)Impossibile compilare l'esempio di Writer Monad da "Learn you a Haskell"

Qualche idea perché? Sto trascurando qualcosa di totalmente ovvio?

(Nonostante la somiglianza in post-titoli, penso che la mia domanda è diversa da this one.)


Ecco il codice (in un file che ho chiamato 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) 

E ecco l'errore in fase di compilazione:

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. 

risposta

14

LYAH è obsoleto in t il suo esempio È necessario utilizzare il metodo di costruzione intelligente writer anziché il costruttore di dati (ora inesistente) Writer.

Per espandere un bit, questi tipi di dati sono stati aggiornati per essere più compatibili con i trasformatori monad. Di conseguenza, esiste un generale WriterT, da utilizzare in una pila di trasformatori monad e un sinonimo di tipo Writer che compone WriterT con Identity. Per questo motivo, non esiste più un costruttore di dati associato specificamente al tipo Writer (poiché Writer è un sinonimo di tipo).

Fortunatamente, nonostante questa complicazione, la soluzione è piuttosto semplice: sostituire Writer con writer.

+0

credo che era ottimista di me per pensare che la sostituzione di '' Writer' con writer' otterrebbe per eseguire :) In questo modo i risultati nel seguente errore per la funzione 'multWithLog' (e un errore simile per la funzione' logNumber'): 'Nessuna istanza per (Monad (writer [String])) derivante da una dichiarazione do'. Continuerò a giocarci. – iceman

+11

@DipakC Lascia la firma del tipo uguale. Sostituisci la funzione chiamata 'Writer' con una chiamata a' writer'. Una lettera iniziale minuscola in una firma di tipo fa sempre riferimento a una variabile di tipo, che non è ciò che vogliamo qui. Vogliamo il tipo concreto 'Writer'. –

+1

Voglio dire, chi non vorrebbe una macchina da scrivere concreta? – N3dst4

0

La versione corretta in GHC 7.10.3 dovrebbe essere così

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)