来自流媒体库的takeWhileM函数的Monadic谓词

时间:2018-05-14 23:52:45

标签: haskell streaming monads

我尝试使用一系列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

1 个答案:

答案 0 :(得分:1)

您未使用基础monad m的任何效果,因此谓词不需要是monadic,而S.takeWhile可以替代使用。

  S.takeWhile predicate ...
  -- or S.takeWhileM (return . predicate)
where 
  predicate (Just x) = x < 5
  predicate Nothing = False