Jeremy Gibbons 및 Bruno C.의 The Essence of the Iterator Pattern에 나와있는 것처럼 하스켈과 Kernighan 및 Ritchie에서 모나드 구성을 사용하여 시연 된 UNIX wc 프로그램을 포팅하려고 비교적 처음입니다. S. Oliveira, 컴파일하는데 어려움을 겪고 있습니다.GHC 8.0.1 오류 (작성자 및 주립 모 더드)
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 인스턴스를 구현하여 사용할 수는 있지만 tail-recursive 형식으로의 변환은 결국'State'처럼 보일 것입니다.'newtype WriterT '= WriterT'(StateT wm a) 파생 (Functor, Applicative, Monad); 인스턴스 (Monoid w, Monad m) => MonadWriter w (WriterT 'w m) 여기서 a = WriterT $ modify'(<> a)'. 다른 모든 효과가 지원되는지는 잘 모르겠지만 아마도. 결국, 당신은 기본적으로'State' 땅으로 되돌아 간다. 확인하기 위해 까다로워 질 수있는 약간의 것들이있다. – dfeuer