Gabriella439 / pipes

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

Add mapMaybe and wither #215

Closed treeowl closed 4 years ago

treeowl commented 4 years ago

These are of course based on witherable, though by that package's standards wither should be witherM.

treeowl commented 4 years ago

I noticed that the other RULES expand things out some more. Is that necessary? If so, I can surely do it.

Gabriella439 commented 4 years ago

@treeowl: It's not necessary. This looks great to me! I'm just waiting for CI at this point

treeowl commented 4 years ago

Do you agree with my use of MaybeT for documentation?

treeowl commented 4 years ago

If so, should the first wither law be written

wither (runMaybeT . lift . f) = mapM f

or is that just silly?

treeowl commented 4 years ago

Eh, I made the doc change. Feel free to modify in merging.

treeowl commented 4 years ago

One other question: how do you like to handle @since annotations for new functions?

treeowl commented 4 years ago

Yes, but what placeholder should I use for the @since version number?

Gabriella439 commented 4 years ago

@treeowl: I wouldn't worry about @since, to be honest

treeowl commented 4 years ago

I've rearranged the documentation a bit to be able to say pretty much all the things without (I hope) too much clutter.

treeowl commented 4 years ago

The laws make me think that mapMaybe relates the pipe category for m to Kleisli Maybe and that wither relates the pipe category for m to Kleisli (MaybeT m). Since I'm generally ignorant of category theory, do you think you could explain what those relationships are called? Are they basically functors or something?

Gabriella439 commented 4 years ago

@treeowl: Yes, that's exactly correct! They would be functors and the laws you wrote would be the functor laws

In fact, you're actually missing one of the functor laws for mapMaybe. You already have one of the two functor laws, which is:

-- Analogous to `fmap (f . g) = fmap f . fmap g`
mapMaybe (f >=> g) = mapMaybe f >-> mapMaybe g

The other functor law that I would expect to see is:

-- Analogous to `fmap id = id`
mapMaybe return = cat

For wither you already have the two functor laws, which would be:

wither (runMaybeT . (MaybeT . f >=> MaybeT . g)) = wither f >-> wither g

wither (runMaybeT . return) = cat
treeowl commented 4 years ago

That law isn't missing. You're just looking on the wrong line. Ready to merge?

Gabriella439 commented 4 years ago

@treeowl: Yeah, this looks great to merge. Thank you for contributing this! 🙂

treeowl commented 4 years ago

Glad I could help!