【发布时间】:2016-12-10 10:58:25
【问题描述】:
我对 Haskell 比较陌生,并尝试使用单子组合移植在 Kernighan 和 Ritchie 中演示的 UNIX wc 程序,如 Jeremy Gibbons 和 Bruno C 的The Essence of the Iterator Pattern 所示。 S. Oliveira,并且在编译时遇到了一些麻烦。这是我的代码:
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
以及编译器错误:
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.
在这两种情况下,我都无法理解我做错了什么。任何帮助将不胜感激。谢谢!
【问题讨论】: