Closed treeowl closed 3 years ago
I don't think it should have its own module, and I think Backwards
should move to Control.Applicative
, but then again this package seems to like a separate module for each type, so I guess that's okay. Your other remarks are totally uncontroversial, and I'll definitely make those changes
One minor concern: not very many types are both Biapplicative
and Applicative
. Should Backwards
have at Applicative
instance at all? On the other hand, it's possible to imagine it as a (conceptually infinite) family
data family Backwards :: k
newtype instance Backwards a = Backwards0 { forwards0 :: a }
newtype instance Backwards f a = Backwards1 { forwards1 :: f a }
newtype instance Backwards f a b = Backwards2 { forwards2 :: f a b }
newtype instance Backwards f a b c = Backwards3 { forwards3 :: f a b c }
...
for turning around constructors of any arity that may be required and providing the appropriate Monoid
, Applicative
, Biapplicative
, etc., instances for all possible arities. So ... I think it's probably okay to think of Data.Biapplicative.Backwards
not as "turning around Biapplicative
" but rather as "turning around NApplicative
for N <= 2
".
Of course, my last comment raises an interesting question: should we actually offer that data family instead? I kind of like it. Almost all the instances can be produced using DerivingVia
, which is kind of cool.
Oh, and even if we don't do that, should we add a Dual
Monoid
instance for Backwards
?
@RyanGlScott Do you have any idea why the older GHCs are balking at this? The only workaround I've found so far is to make every single derived instance standalone, which is really awful.
I think it's probably okay to think of
Data.Biapplicative.Backwards
not as "turning aroundBiapplicative
" but rather as "turning aroundNApplicative
forN <= 2
".
I agree.
Of course, my last comment raises an interesting question: should we actually offer that data family instead?
I don't have a strong opinion on this, but if we do go that route, I think we should do it in a separate commit. There are other data types in bifunctors
that, conceptually, could also be made into data families (e.g., Fix
, Biap
, and possibly others).
Do you have any idea why the older GHCs are balking at this?
This is likely due to an old GHC bug of some sort, but I'm hard-pressed to remember which one it is. Unfortunately, we may just have to live with standalone deriving if we pursue this design.
@RyanGlScott, all right. I pulled the data family stuff out of this PR; we can consider it elsewhere.
Even if I can find a way to make the StandaloneDeriving
bearable (at least temporarily), I think some Microsurgery
will be required to produce the Generic
and Generic1
instances. I didn't check if that's an issue in 8.8, or only in 8.6, but 8.6 just can't derive those for Backwards
at all. I don't know if it's an issue with polykinded data families specifically, data families in general, or what.
Almost done, but I want custom Show
and Read
instances to avoid the record syntax noise.
I've had second thoughts about Backwards
. Might be better to go with separate types for reversing n-Applicatives for each n, while perhaps making each a data family for constructors of different arity. It's just not obvious the way Reverse
is.
I've had second thoughts about
Backwards
. Might be better to go with separate types for reversing n-Applicatives for each n, while perhaps making each a data family for constructors of different arity.
I'm fine with whichever route you end up choosing, provided that the final design is clearly explained in the Haddocks.
@RyanGlScott , I think that covers everything. I also added a slew of derived instances. Note: I think the Show
and Read
approaches taken here should be applied to things like Tannen
and Biff
as well, but that's for a different PR.
Biapplicative
instances are reversable just likeApplicative
ones. Add aBackwards
type to demonstrate that.