我尝试使用一系列monadic值(由streaming
库生成)直到满足某个条件,但我在编写一个我可以传递给的函数时遇到问题takeWhileM
。
我想我正在咆哮着正确的树,但我怀疑我的stream
功能的签名可能是错误的。
有人能指出我在正确的方向吗?
代码:
#!/usr/bin/env stack
import Streaming
import qualified Streaming.Prelude as S
import Data.Maybe
stream :: (Enum a, Num a, Monad m) => Stream (Of (Maybe a)) m ()
stream = S.takeWhileM predicate $ S.each $ [Just x | x <- [1..]]
where
predicate x = do
x' <- x
return $ x' < 5
main :: IO ()
main = do
S.print stream
print "done"
这就是我得到的错误:
test.hs:8:10: error:
• Couldn't match type ‘m’ with ‘Maybe’
‘m’ is a rigid type variable bound by
the type signature for:
stream :: forall a (m :: * -> *).
(Enum a, Num a, Monad m) =>
Stream (Of (Maybe a)) m ()
at test.hs:7:1-64
Expected type: Stream (Of (Maybe a)) m ()
Actual type: Stream (Of (Maybe a)) Maybe ()
• In the expression:
S.takeWhileM predicate $ S.each $ [Just x | x <- [1 .. ]]
In an equation for ‘stream’:
stream
= S.takeWhileM predicate $ S.each $ [Just x | x <- [1 .. ]]
where
predicate x
= do x' <- x
....
• Relevant bindings include
stream :: Stream (Of (Maybe a)) m () (bound at test.hs:8:1)
|
8 | stream = S.takeWhileM predicate $ S.each $ [Just x | x <- [1..]]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我也尝试了predicate
这样的事情并没有奏效(但我真的不想手工提取monadic值,希望<-
可以做一些魔术,以便我可以将其用于其他monad):
stream :: (Enum a, Num a, Monad m) => Stream (Of (Maybe a)) m ()
stream = S.takeWhileM predicate $ S.each $ [Just x | x <- [1..]]
where
predicate x = do
x' <- x
case x' of
Just value -> return $ value < 5
Nothing -> return $ False
答案 0 :(得分:1)
您未使用基础monad m
的任何效果,因此谓词不需要是monadic,而S.takeWhile
可以替代使用。
S.takeWhile predicate ...
-- or S.takeWhileM (return . predicate)
where
predicate (Just x) = x < 5
predicate Nothing = False