Open Icelandjack opened 7 years ago
@ekmett deliberately chose the current design, see https://github.com/ekmett/bifunctors/pull/8#issuecomment-121932733.
That being said, perhaps there's room for this incarnation as well (under a different name).
I respect unifying the kind structure and I hope that given #12369
they can be unified formally
data family Fix :: (k -> *) -> k
data instance Fix f = In (f (Fix f))
data instance Fix f a = In1 (f (Fix f) a)
data instance Fix f a b = In2 (f (Fix f) a b)
Maybe the underlying representation doesn't have to change, and we can inline Reverse
/ Backwards
instance Bifoldable p => Foldable (Fix p) where
foldMap f (In p) = getDual (bifoldMap (Dual . foldMap f) (Dual . f) p)
instance Bitraversable p => Traversable (Fix p) where
traverse :: Applicative f => (a -> f a') -> (Fix p a -> f (Fix p a'))
traverse f (In p) = In <$> forwards (bitraverse (Backwards . traverse f) (Backwards . f) p)
instance Biapplicative p => Applicative (Fix p) where
pure a = In (bipure (pure a) a)
In p <*> In q = In (biliftA2 (<**>) (&) q p)
This restores the correct ordering
>>> traverse (\a -> Const [a]) (1:::2:::3:::4:::Nil)
Const [1,2,3,4]
>>> toList (1:::2:::3:::4:::Nil)
[1,2,3,4]
(#12369
has been implemented)
(#12369 has been implemented)
Great! FWIW, I doubt we are going to be seeing any return-kind-polymorphic data families put into this package any time soon due to bifunctors
' wide support window (the same reason we are holding off on #37 for now). This does sound like the sort of thing that would be great to explore in a different library, however.
I don't generally have a particular problem with enabling new features conditional on the new version, and providing definitions that just don't get exposed on old compilers.
In any case, I'm not sure what exactly is being proposed here anymore. There seem to be any number of possible changes that @Icelandjack is hinting at:
Fix
implementationFix
with different argument order alongside the one from Data.Bifunctor.Fix
(In the same module? A different module? I'm not sure.)Using a return-kind-polymorphic definition. (Whether that should replace the old one or live alongside the old one is also unclear to me.)
@Icelandjack, do one of those points accurately characterize what you're proposing?
Sure. It's just a general principle. The best way to apply it here has to be hammered out. It may not belong here in bifunctors simply because bifunctor isn't the base case.
The order of
Fix
is unfortunate, it means that given a standard base functorwe get an unexpected order of elements
I had the same problems with defining
newtype ZipList a = ZL (Fix (Tannen Maybe (,))
from #57 where I need to wrap it inReverse
to get theFoldable
I want.if it were the other way round like The Essence of the Iterator Pattern
we would get the right ordering and the argument of
fold
fits the shape of an algebra