Gabriella439 / pipes

Compositional pipelines

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Consider writing toList for list fusion

treeowl opened this issue · comments

toList should, I believe, be able to fuse with list folds. This would be useful if someone uses pipes to implement an action but exposes a list interface. Something like this:

toList :: Producer a Identity () -> [a]
toList pipe = build (\c n ->
  let
    loop p = case p of
       Request v _ -> closed v
       Respond a fu -> a `c` loop (fu ())
       M m -> loop (runIdentity m)
       Pure _ -> n
  in loop pipe)
{-# INLINE toList #-}

Yeah, I like this idea. Another approach that we could also do in addition is to implement a Foldable instance for ListT, which would be equivalent.

Yes. That actually gives a toList for free, which of course leads to the horrible choice of whether to re-export Data.Foldable.toList (re-exports are evil) or deprecate toList (deprecation is evil). Sigh. Clearly, ListT Identity can and should be made Foldable. I don't think that can be done for ListT m any more generally, but you'd know better.

I think you can define this instance:

instance Foldable m => Foldable (ListT m a)

... and there's a convenient Foldable instance for Identity, so everything works out perfectly, you get extra generality, and you don't need FlexibleInstances!

I would probably neither re-export Data.Foldable.toList nor deprecate Pipes.Prelude.toList. There's no point deprecating Pipes.Prelude.toList since people import that qualified anyway.