Монадический предикат для функции takeWhileM из потоковой библиотеки - PullRequest
0 голосов
/ 15 мая 2018

Я пытаюсь использовать поток монадических значений (созданных библиотекой 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, как это, и это не сработало (но я действительно не хочу извлекать монадическое значение вручную, надеялся, что <- может сотворить магию, чтобы я мог использовать это для других монад):

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 голосов
/ 15 мая 2018

Вы не используете никакого эффекта базовой монады m, поэтому предикат не обязательно должен быть монадическим, и вместо него можно использовать S.takeWhile.

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