Gabriella439 / pipes

Compositional pipelines
BSD 3-Clause "New" or "Revised" License
487 stars 72 forks source link

Additional pipes prelude functions #174

Open andrewthad opened 8 years ago

andrewthad commented 8 years ago

Would you accept catMaybes and mapMaybe functions that are specialized to work on pipes? They would have the following type signatures:

catMaybes :: Pipe (Maybe a) a m r
mapMaybe :: (a -> b) -> Pipe (Maybe a) b m r

Also worth considering would be lefts and rights, which would be:

lefts :: Pipe (Either a b) a m r
rights :: Pipe (Either a b) b m r
michaelt commented 8 years ago

Note that catMaybes and rights are both specializations of Pipes.Prelude.concat Maybe the documentation for concat should be elaborated more to bring this out? At the moment it just says

  -- | Flatten all 'Foldable' elements flowing downstream

Pipes.Prelude doesn't really use examples, but something like this might make the meaning of 'flatten' clearer

>>> runEffect $ each [[1], [], [2]] >-> P.concat >-> P.print
1
2
>>> runEffect $ each [Just 1, Nothing, Just 2] >-> P.concat >-> P.print
1
2
>>> runEffect $ each [Right 1, Left "message", Right 2] >-> P.concat >-> P.print
1
2

It's a little annoying, by the way, that the generalization of Prelude.concat to Foldable made the opposite decision

 concat :: Foldable t => t [a] -> [a]

rather than

 concat :: Foldable t =>  [t a] -> [a]
Gabriella439 commented 8 years ago

In addition to what @michaelt said there is Pipes.Prelude.mapFoldable, too

mitchellwrosen commented 7 years ago

How about intersperse?

intersperse :: Monad m => a -> Producer' a m r -> Producer' a m r
Gabriella439 commented 7 years ago

@mitchellwrosen You can implement intersperse in terms of other utilities:

interperse x p = for p (\y -> do yield x; yield y) >-> Pipes.Prelude.drop 1
treeowl commented 4 years ago

I didn't see this before, but I just added mapMaybe and wither. @michaelt makes a good point about flattening, but I think it's worth adding a now-common idiom.