作为学习Haskell,Conduit和Monads的练习,我想创建一个告诉输入值并将其传递的管道。
代码很简单,但是我遇到的编译错误对我来说仍然是个隐秘的问题:
log =
await >>= \case
Nothing -> return ()
Just value -> do
tell [value]
yield value
runWriter $ CL.sourceList ["a", "b"] $= log $$ CL.consume
错误:
No instance for (MonadWriter [o0] m0) arising from a use of ‘tell’
The type variables ‘m0’, ‘o0’ are ambiguous
Relevant bindings include
value :: o0
(bound at /home/vagrant/workspace/dup/app/Main.hs:241:10)
logg :: ConduitM o0 o0 m0 ()
(bound at /home/vagrant/workspace/dup/app/Main.hs:238:1)
Note: there are several potential instances:
instance MonadWriter w m => MonadWriter w (ConduitM i o m)
-- Defined in ‘conduit-1.2.6.4:Data.Conduit.Internal.Conduit’
instance MonadWriter w m =>
MonadWriter
w (conduit-1.2.6.4:Data.Conduit.Internal.Pipe.Pipe l i o u m)
-- Defined in ‘conduit-1.2.6.4:Data.Conduit.Internal.Pipe’
instance [safe] MonadWriter w m =>
MonadWriter w (Control.Monad.Trans.Resource.Internal.ResourceT m)
-- Defined in ‘Control.Monad.Trans.Resource.Internal’
...plus 11 others
In a stmt of a 'do' block: tell [value]
In the expression:
do { tell [value];
yield value }
In a case alternative:
Just value
-> do { tell [value];
yield value }
这对我有用:
{-# LANGUAGE FlexibleContexts #-}
import Data.Conduit
import Control.Monad.Writer
import qualified Data.Conduit.List as CL
doit :: MonadWriter [i] m => Conduit i m i
doit = do
x <- await
case x of
Nothing -> return ()
Just v -> do tell [v]; yield v; doit
foo = runWriter $ CL.sourceList ["a", "b", "c"] =$= doit $$ CL.consume
请注意,我将名称从更改为log
,doit
以避免名称与冲突Prelude.log
。
更新
如果您从以下内容开始:
import Data.Conduit
import Control.Monad.Writer
import qualified Data.Conduit.List as CL
doit = do
x <- await
case x of
Nothing -> return ()
Just v -> do tell [v]; yield v; doit
您将收到两个错误:
No instance for (Monad m0) arising from a use of ‘await’
...
No instance for (MonadWriter [o0] m0) arising from a use of ‘tell’
...
由于doit
是顶级功能,经验会告诉您,单态性限制可能在这里起作用。确实,在添加之后:
{-# LANGUAGE NoMonomorphismRestriction #-}
您只会得到一个错误:
Non type-variable argument in the constraint: MonadWriter [o] m
(Use FlexibleContexts to permit this)
...
在添加之后FlexibleContexts
,代码将编译。
现在,您可以询问以下类型doit
:
ghci> :t doit
doit :: MonadWriter [o] m => ConduitM o o m ()
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句