@@ -39,6 +39,7 @@ module Control.Fold
3939 , minimum
4040 , elem
4141 , notElem
42+ , distributed
4243 ) where
4344
4445import Prelude
@@ -48,11 +49,14 @@ import Control.Alt ((<|>))
4849import Control.Apply (lift2 )
4950import Control.Comonad (class Comonad , extract )
5051import Control.Extend (class Extend )
52+ import Data.Distributive (class Distributive , cotraverse )
5153import Data.Foldable (class Foldable )
54+ import Data.Function (applyFlipped )
5255import Data.HeytingAlgebra (ff , tt )
5356import Data.Maybe (Maybe (..))
5457import Data.Monoid (class Monoid , mempty )
5558import Data.Profunctor (class Profunctor , dimap , lmap )
59+ import Data.Profunctor.Closed (class Closed , closed )
5660import Data.Traversable (class Traversable )
5761
5862-- | A left fold, which takes zero or more values of type `a` as input
@@ -89,6 +93,10 @@ foldl fold xs = extract (Foldable.foldl (\(Fold o) -> o.step) fold xs)
8993scanl :: forall f a b . Traversable f => Fold a b -> f a -> f b
9094scanl fold xs = map extract (Traversable .scanl (\(Fold o) -> o.step) fold xs)
9195
96+ -- | Fold over entire collections of inputs, producing a collection of outputs.
97+ distributed :: forall f a b . Distributive f => Fold a b -> Fold (f a ) (f b )
98+ distributed = dimap applyFlipped (flip cotraverse id) <<< closed
99+
92100-- | `Fold` values in some `Monoid`.
93101mconcat :: forall m . Monoid m => Fold m m
94102mconcat = unfoldFold_ mempty append
@@ -163,6 +171,9 @@ instance profunctorFold :: Profunctor Fold where
163171 step = f >>> o.step >>> dimap f g
164172 finish = o.finish >>> g
165173
174+ instance closedFold :: Closed Fold where
175+ closed f = unfoldFold (const f) (lift2 (flip stepFold)) (extract <<< _)
176+
166177instance functorFold :: Functor (Fold a ) where
167178 map f (Fold o) = Fold { step, finish }
168179 where
0 commit comments