Open treeowl opened 1 year ago
If this isn't a good home for this function, I suppose I can give it its own package, but I fear it will be very lonely there.
Indeed, my only concern with this patch is the fact that it isn't obviously connected to the API that bifunctors
offers unless you know unzipWith
is implemented under the hood.
One idea (which I'm not sure is good or not, but an idea nonetheless) is to move this to Data.Biapplicative.LazyPair
and export the LazyPair
data type alongside unzipWith
, as LazyPair
is more obviously a Biapplicative
thing.
Indeed, my only concern with this patch is the fact that it isn't obviously connected to the API that
bifunctors
offers unless you knowunzipWith
is implemented under the hood.One idea (which I'm not sure is good or not, but an idea nonetheless) is to move this to
Data.Biapplicative.LazyPair
and export theLazyPair
data type alongsideunzipWith
, asLazyPair
is more obviously aBiapplicative
thing.
Yes, I agree there's a case to be made for LazyPair
—but maybe more than one! This version NOINLINE
s a bunch of stuff, which is exactly what you want—sometimes. Not so much other times. And I don't think there's much chance most people would see a module called Data.Biapplicative.LazyPair
(or perhaps more likely Data.Bifunctor.LazyPair
) and realize that was the place to find an unzipping function. So I'm pretty unsatisfied with all the options I've seen or imagined thus far.
And I don't think there's much chance most people would see a module called
Data.Biapplicative.LazyPair
(or perhaps more likelyData.Bifunctor.LazyPair
) and realize that was the place to find an unzipping function. So I'm pretty unsatisfied with all the options I've seen or imagined thus far.
Yes, I certainly believe that. There is a similar parallel to Data.Traversable
's mapAccumL
and mapAccumR
functions, which are built on top of state transformers under the hood. It definitely would be out of place to export mapAccumL
and mapAccumR
from Control.Monad.Trans.State
, for instance.
The same reasoning could be applied here: if someone wanted to find an unzipWith
function, then bifunctors
is an unlikely home for it. The would suggest that unzipWith
deserves to live in a separate package, unless you are fine with finding a way to dress it up in bifunctors
clothing.
A separate package has its own entirely nontrivial discovery problems. Can we at least agree on adding two lazy pair types (one with NOINLINE
s and one without) and a strict one to bifunctors
? Can you come up with names and module names?
Can we at least agree on adding two lazy pair types (one with
NOINLINE
s and one without) and a strict one tobifunctors
?
Sure, I would be fine with that. As far as names go, do you have any objections to LazyPair
? I would be tempted to put these in modules named Data.Bifunctor.LazyPair
and Data.Bifunctor.LazyPair.NoInline
, each exposing the same API.
I'm a bit nervous about what people might make of the latter name, but I don't have a great alternative. The naming on the strict side is hard too; when I think of a "strict pair" I think of one with strict fields. Maybe NonLazy
? Blech.
We can use
traverseBia
to implement a lazyunzipWith
function for generalTraversable
instances. While it's trivial in principle, preventing it from leaking memory turns out to be rather tricky, so I think it makes sense to offer it as a function rather than just documenting the possibility.