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.