Closed andrewthad closed 8 years ago
Hi, @andrewthad I had thought of catMaybes
before. I didn't include it because I was closely following the Pipes.Prelude
which assimilates this to concat :: Foldable t => Stream (Of (t a)) -> Stream (Of a) m r
(as we would put it here). Now that the API is clearer, though, it seems it would be better to include catMaybes
and mapMaybe
after all. First, I would sort of like the Streaming.Prelude
to be as close as possible to the list handling in Prelude
Data.List
and the other basic base modules etc. Then you can use it without thinking about clever identifications like that, and without mastering the api as a whole, and getting involved with a 'streaming IO framework' and figuring out what obvious things from Prelude etc. might have turned into. Interestingly, the new type of Prelude.concat :: Foldable t => t [a] -> [a]
would lead one away from suspecting that Pipes/Streaming.concat
would work the way it does; the order of t
and []
should be swapped. Second, implemented you have done above, mapMaybe
will definitely be a bit faster than S.concat . S.map f
; and catMaybe
maybe faster in some contexts by being specialized and direct.
You can turn catMaybe
and mapMaybe
into a patch if you like, or I can write them in. In general all recursive functions are marked with an {-#INLINABLE mapMaybe #-}
pragma. That way the source can gravitate toward main
and the compiler has a lot of chances to see through the program as a whole. (This too follows the approach of pipes)
Thanks!
Thanks for the background on that. It's helpful for understanding motivations and goals. I'll put up a PR in the next half hour.
I've written two functions that I need for a project I'm working on. I think these could be added to
Streaming.Prelude
ascatMaybes
andmapMaybe
, since they are analogous to the functions fromData.Maybe
with the same names. I don't think any strictness annotations are required, but I'm not really good at knowing when to use them.