>>>>> Daniel Díaz <diaz.carr...@gmail.com> writes:

> While tinkering with the foldl package I found a way to convert some pipes
> from pipes-parse into folds from foldl.

You can go even a step further with producers, and encode them as a CPS-based
fold, i.e.:

    newtype Source m a = Source 
        { getSource :: forall r. Cont (r -> EitherT r m r) a }
        deriving Functor

    type Conduit a m b = Source m a -> Source m b
    type Sink a m r    = Source m a -> m r

I do this in the simple-conduit package, but am planning to part the idea over
to pipes as well.  This is what a converter from conduit Producers to such a
representation looks like:

adaptFrom :: forall m a. MonadBaseControl IO m => C.Producer m a -> Source m a
adaptFrom (C.ConduitM m) = source go
  where
    go :: r -> (r -> a -> EitherT r m r) -> EitherT r m r
    go z yield = f z m
      where
        f r (C.HaveOutput p c o) = yield r o >>= \r' -> f r' p `finally` lift c
        f r (C.NeedInput _ u)    = f r (u ())
        f r (C.Done ())          = return r
        f r (C.PipeM mp)         = lift mp >>= f r
        f r (C.Leftover p l)     = yield r l >>= flip f p

And for folds from foldl:

    fromFoldM :: Monad m => FoldM m a b -> Sink a m b
    fromFoldM (FoldM step start done) src =
        start >>= (\r -> sink r ((lift .) . step) src) >>= done
    
    toFoldM :: Monad m => Sink a m b -> (forall r. FoldM m a r -> m r) -> m b
    toFoldM s f = s $ source $ \z yield ->
        lift $ f $ FoldM ((unwrap .) . yield) (return z) return

John

-- 
You received this message because you are subscribed to the Google Groups 
"Haskell Pipes" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to haskell-pipes+unsubscr...@googlegroups.com.
To post to this group, send email to haskell-pipes@googlegroups.com.

Reply via email to