如何让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
但我不能让它与管道合作。
答案 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]