-
Notifications
You must be signed in to change notification settings - Fork 18
Description
Currently the Alternative instance for Compose f g is:
instance (Alternative f, Applicative g) => Alternative (Compose f g) where
empty = Compose empty
(<|>) = coerce ((<|>) :: f (g a) -> f (g a) -> f (g a))
:: forall a . Compose f g a -> Compose f g a -> Compose f g aThe some and many methods thus get their default definitions. If f has an explicit definition for some or many in Alternative f, then this gets ignored. If they are more efficient than the defaults, then this efficiency is discarded in Alternative (Compose f g).
In some cases, the resulting some and many in Alternative (Compose f g) are completely broken. This occured to me with
(Monoid ann) => Alternative (Compose (Prod r e t) ((,) ann))where Prod r e t is from Earley. In the case of Earley, some and many have special case definitions, and using the default definitions instead results in infinite loops.
I propose the following definitions for some and many:
some :: (Alternative f, Applicative g) => Compose f g a -> Compose f g [a]
some (Compose v) = Compose (sequenceA <$> some v)
many :: (Alternative f, Applicative g) => Compose f g a -> Compose f g [a]
many (Compose v) = Compose (sequenceA <$> many v)These definitions make sure to use the implementations of some and many from Alternative f.
A related (accepted) proposal adds explicit definitions to Foldable (Compose f g): #57