私は、ハスケルにとって比較的新しく、Jeremy GibbonsとBruno C.によってThe Essence of the Iterator Patternに示されているように、KernighanとRitchieで実演されたUNIX wcプログラムをモナド構成で移植しようとしています。 S. Oliveira、それをコンパイルするのにいくつかの問題がありました。ここに私のコードだ:GHC 8.0.1 Writer and State monadsのエラー
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.
私はここでいずれの場合も、私が間違ってやっているのか理解することはできません。どんな助けでも大歓迎です。ありがとう!
実際、State(Integer、Bool)はおそらくもっと良いでしょう。 'Writer'は' Sum Integer'のようなものではうまく動作しません。 – dfeuer
@dfeuerあなたはそれを定量化できますか?あなたは怠惰を話しますか? –
はい。 「Control.Monad.Writer.Strict」でも「ログ」には怠惰です。独自のMonadWriterインスタンスを実装して使用することもできますが、末尾再帰型への変換は 'State'のようになります。'newtype WriterT 'は、(Functor、Applicative、Monad)を導出するWriterT'(StateT w m a)である。インスタンス(Monoid w、Monad m)=> MonadWriter w(WriterT 'w m)ここでa = WriterT $ modify'(<> a) '。他のすべてのエフェクトがサポートされているかどうかはわかりませんが、おそらくそれはわかりません。結局、あなたは基本的に '国家 'の土地に戻ってきます。いくつかのものがボンネットの下にあり、確認するのが難しいかもしれません。 – dfeuer