编辑前回答原始问题:
据我所知,这里应该使用流媒体方法。但我不明白如何使用例如
list-t
包裹
如果你的monad足够懒惰,你可以使用常规列表:
import Control.Monad (filterM)
import Control.Monad.Trans.State.Lazy (State, get)
import Data.Set (Set, member)
filterStateLazy :: Ord a => [a] -> State (Set a) [a]
filterStateLazy = filterM $ \x -> do
s <- get
pure $ x `member` s
-- >>> import Control.Monad.Trans.State.Lazy (evalState)
-- >>> import qualified Data.Set as Set
-- >>> take 5 . evalState (filterStateLazy [1..]) $ Set.fromList [1, 6, 22, 39, 54]
-- [1,6,22,39,54]
如果你真的想
ListT
不过,您也可以使用它,并且不需要懒惰的monad:
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
import ListT
import Control.Monad.State.Strict
import Data.Set (Set, member)
filterStateLazy :: (MonadState (Set a) m, Ord a) => ListT m a -> ListT m a
filterStateLazy (ListT run) = ListT $ run >>= \case
Nothing -> return Nothing
Just (x, rest) -> do
s <- get
if x `member` s
then pure $ Just (x, filterStateLazy rest)
else uncons $ filterStateLazy rest
-- >>> import Control.Monad.Trans.State.Lazy (evalState)
-- >>> import qualified ListT as ListT
-- >>> import qualified Data.Set as Set
-- >>> evalState (ListT.toList . ListT.take 5 . filterStateLazy $ ListT.fromFoldable [1..]) $ Set.fromList [1, 6, 22, 39, 54]
-- [1,6,22,39,54]