blamario / grampa

Grammatical parsers - combinator library for parsing general context-free grammars
BSD 2-Clause "Simplified" License
36 stars 13 forks source link

Traversable compositions #7

Open treeowl opened 6 years ago

treeowl commented 6 years ago

Unfortunately, there seem to be several ways to make a Traversable from a composition of two types. Perhaps it would make sense to offer newtypes to cover some of them.

blamario commented 6 years ago

Can you elaborate a bit? Or send a PR, better yet?

treeowl commented 6 years ago

I don't think I'm ready to send a PR for this one; I don't understand the space well enough. But there are at least two R2. Traversable (R2.Compose t u) instances. For one, there's a Prelude.Traversable l constraint on t and an R2.Traversable constraint on u. For the other I've found, there's an R2.Traversable constraint on t and a constraint I don't really understand on u.

blamario commented 6 years ago

Do you think there is any alternative to this Rank2.Functor instance?

instance (Rank1.Functor g, Rank2.Functor h) => Rank2.Functor (Compose g h) where
   f <$> ~(Compose a) = Compose ((f <$>) Rank1.<$> a)
treeowl commented 6 years ago

Yes. The weakest alternative I see in the other direction is

instance (Functor f, Functor1 g) => Functor (Compose f g) where
   f <$> Compose xs = Compose (fmap1 f <$> xs)

class Functor1 f where
   fmap1 :: (forall x. p x -> q x) -> f p a -> f q a

These instances don't actually overlap, since they have different kinds, but they're rather FlexibleInstancesish (without, I think, needing that extension). Ed Kmett tends to be wary of such for inference reasons.

treeowl commented 6 years ago

Er... I take that back. They probably do overlap.

treeowl commented 6 years ago

I guess my Functor1 is actually McBride's IFunctor class, with

type f :-> g = forall a. f a -> g a
imap :: (p :-> q) -> (f p :-> f q)