Is your feature request related to a problem? Please describe.
At the moment, Data.Monoid.Linear.Semigroup is defined as
class Prelude.Semigroup a => Semigroup a where
(<>) :: a %1 -> a %1 -> a
with a Prelude.Semigroup superclass constraint. Theorically, this is correct. Indeed, any linear semigroup can be made into a non-linear semigroup just by upcasting (<>) :: a %1 -> a %1 -> a to (<>) :: a -> a -> a. A NonLinear newtype also exists in Data.Monoid.Linear.Internal.Semigroup to easily derive Prelude.Semigroup from (linear) Semigroup.
However, things get harder when we try to write a (linear) Semigroup instance for Ap f a. In base, we have instance (Prelude.Applicative f, Prelude.Semigroup a) => Prelude.Semigroup (Ap f a). In linear-base, we would like to have instance (Data.Functor.Linear.Applicative f, Data.Monoid.Linear.Semigroup a) => Data.Monoid.Linear.Semigroup (Ap f a).
But such an instance head requires Prelude.Semigroup (Ap f a) (because of the Prelude.Semigroup => Data.Monoid.Linear.Semigroup relationship), which is not deducible because f is a Data.Functor.Linear.Applicative, not a Prelude (non-linear) one.
Unfortunately, we can't add instance (Data.Functor.Linear.Applicative f, Prelude.Semigroup a) => Prelude.Semigroup (Ap f a), because this has the same head as instance (Prelude.Applicative f, Prelude.Semigroup a) => Prelude.Semigroup (Ap f a) already present in base.
Also, Semigroup and Monoid are the only linear classes which have their non-linear counterpart as superclasses, although it would also make sense for Ord or Eq for example.
Describe the solution you'd like
I see three potential solutions:
- Breaking the
Prelude.Semigroup => Data.Monoid.Linear.Semigroup and Prelude.Monoid => Data.Monoid.Linear.Monoid relationships, allowing us to add the instance (Data.Functor.Linear.Applicative f, Data.Monoid.Linear.Semigroup a) => Data.Monoid.Linear.Semigroup (Ap f a)
- OR keeping them, but adding the same kind of reliationship for
Eq, Ord, and any eligible linear class, and then
- Not exporting the
Ap newtype
- OR adding a
LinAp newtype
Is your feature request related to a problem? Please describe.
At the moment,
Data.Monoid.Linear.Semigroupis defined aswith a
Prelude.Semigroupsuperclass constraint. Theorically, this is correct. Indeed, any linear semigroup can be made into a non-linear semigroup just by upcasting(<>) :: a %1 -> a %1 -> ato(<>) :: a -> a -> a. ANonLinearnewtype also exists inData.Monoid.Linear.Internal.Semigroupto easily derivePrelude.Semigroupfrom (linear)Semigroup.However, things get harder when we try to write a (linear)
Semigroupinstance forAp f a. Inbase, we haveinstance (Prelude.Applicative f, Prelude.Semigroup a) => Prelude.Semigroup (Ap f a). Inlinear-base, we would like to haveinstance (Data.Functor.Linear.Applicative f, Data.Monoid.Linear.Semigroup a) => Data.Monoid.Linear.Semigroup (Ap f a).But such an instance head requires
Prelude.Semigroup (Ap f a)(because of thePrelude.Semigroup => Data.Monoid.Linear.Semigrouprelationship), which is not deducible becausefis aData.Functor.Linear.Applicative, not aPrelude(non-linear) one.Unfortunately, we can't add
instance (Data.Functor.Linear.Applicative f, Prelude.Semigroup a) => Prelude.Semigroup (Ap f a), because this has the same head asinstance (Prelude.Applicative f, Prelude.Semigroup a) => Prelude.Semigroup (Ap f a)already present inbase.Also,
SemigroupandMonoidare the only linear classes which have their non-linear counterpart as superclasses, although it would also make sense forOrdorEqfor example.Describe the solution you'd like
I see three potential solutions:
Prelude.Semigroup => Data.Monoid.Linear.SemigroupandPrelude.Monoid => Data.Monoid.Linear.Monoidrelationships, allowing us to add theinstance (Data.Functor.Linear.Applicative f, Data.Monoid.Linear.Semigroup a) => Data.Monoid.Linear.Semigroup (Ap f a)Eq,Ord, and any eligible linear class, and thenApnewtypeLinApnewtype