如何使管道成为"可折叠"

时间:2015-04-04 09:14:58

标签: haskell typeclass

如何让Producer成为可折叠的实例,所以:

foldr f2 init2 $ Data.Conduit.List.unfold f init

愉快地返回一个值。

我很轻松地使用Streams完成了这项工作,如下所示:

instance Foldable (Data.Vector.Fusion.Stream.Stream) where
  foldr = Data.Vector.Fusion.Stream.foldr

但我不能让它与管道合作。

1 个答案:

答案 0 :(得分:2)

正如迈克尔上面提到的,直接在管道上实施Foldable是不可能的。这是因为给定了类型:

data ConduitM i o m r = ...

我们要折叠的参数(o)不在最终位置。

也就是说,我们可以使用newtype解决这个问题,这可以让我们改变参数。像这样:

import Data.Functor.Identity
import Data.Conduit
import qualified Data.Conduit.List as CL
import qualified Data.Foldable as F

newtype FoldableSource a = FoldableSource (ConduitM () a Identity ())

instance F.Foldable FoldableSource where
    foldMap f (FoldableSource s) = runIdentity $ s $$ CL.foldMap f
    foldl' f z (FoldableSource s) = runIdentity $ s $$ CL.fold f z
    -- GHC 7.10 only
    -- toList (FoldableSource s) = runIdentity $ s $$ CL.consume s

-- A silly example
main = print $ F.sum $ FoldableSource $ CL.sourceList [1..10]