lude

Haskell prelude alternative
git clone git://git.rr3.xyz/lude | git clone gits://git.rr3.xyz/lude
Log | Files | Refs | README | LICENSE

commit c15bc6c5431ec7c8edf018c294551f08d943a536
parent 99272a8cfadf876e5a5630cb638b85c2ca6c1296
Author: Robert Russell <robert@rr3.xyz>
Date:   Thu, 15 Oct 2026 21:10:22 -0700

Algebra.Magma: rename/refactor to make less clunky

Diffstat:
Msrc/Lude/Algebra/Magma.hs | 857+++++++++++++++++++++++++++++++++++++++++--------------------------------------
1 file changed, 450 insertions(+), 407 deletions(-)

diff --git a/src/Lude/Algebra/Magma.hs b/src/Lude/Algebra/Magma.hs @@ -2,14 +2,14 @@ {-# LANGUAGE UndecidableSuperClasses #-} module Lude.Algebra.Magma ( - -- * Magma tags - MagmaK, - Combinative, - Additive, - Multiplicative, + -- * Magma operations + MagmaOpK, + Combination, + Addition, + Multiplication, -- * Semigroups - IsSemigroup_ (..), + IsSemigroupWith (..), IsSemigroup, combine, (<>), @@ -22,97 +22,102 @@ module Lude.Algebra.Magma ( (*), -- * Partial cancellation - PartiallyCancellableL_ (..), - PartiallyCancellableR_ (..), - PartiallyCancellable_, - PartiallyCancellableL, - cancelL', + PartiallyCancellableL (..), + PartiallyCancellableR (..), + PartiallyCancellable, + PartiallyStrippableL, + pstripL, (\\!), - PartiallyCancellableR, - cancelR', + PartiallyStrippableR, + pstripR, (//!), - PartiallyCancellable, - cancel', + PartiallyStrippable, + pstrip, PartiallySubtractableL, - subtractL', + psubL, PartiallySubtractableR, - subtractR', + psubR, PartiallySubtractable, - subtract', - sub', + psubtract, + psub, (-!), PartiallyDividableL, - divideByL', + pdivL, (\!), PartiallyDividableR, - divideByR', + pdivR, (/!), PartiallyDividable, - divideBy', + pdiv, -- * Decidable cancellation - DecidablyCancellableL_ (..), - DecidablyCancellableR_ (..), - DecidablyCancellable_, - DecidablyCancellableL, - tryCancelL#, - (\\?#), + DecidablyCancellableL (..), tryCancelL, + DecidablyCancellableR (..), + tryCancelR, + DecidablyCancellable, + DecidablyStrippableL, + tryStripL#, + (\\?#), + tryStripL, (\\?), - DecidablyCancellableR, - tryCancelR#, + DecidablyStrippableR, + tryStripR#, (//?#), - tryCancelR, + tryStripR, (//?), - DecidablyCancellable, - tryCancel#, - tryCancel, + DecidablyStrippable, + tryStrip#, + tryStrip, DecidablySubtractableL, - trySubtractL#, - trySubtractL, + trySubL#, + trySubL, DecidablySubtractableR, - trySubtractR#, - trySubtractR, + trySubR#, + trySubR, DecidablySubtractable, - trySubtract#, - trySubtract, + trySub#, + (-?#), + trySub, + (-?), DecidablyDividableL, - tryDivideByL#, + tryDivL#, (\?#), - tryDivideByL, + tryDivL, (\?), DecidablyDividableR, - tryDivideByR#, + tryDivR#, (/?#), - tryDivideByR, + tryDivR, (/?), DecidablyDividable, - tryDivideBy#, - tryDivideBy, + tryDiv#, + tryDiv, -- * Monoids - IsMonoid_ (..), + IsMonoidWith (..), IsMonoid, - neutral, + nil, IsAddMonoid, zero, IsMulMonoid, one, -- * Partial inverses - PartiallyHasInverses_ (..), - PartiallyHasInverses, - invert', + PartiallyHasInverses (..), + PartiallyHasUndos, + pundo, PartiallyHasNegations, - negate', + pnegate, PartiallyHasReciprocals, - recip', + precip, -- * Decidable inverses - DecidablyHasInverses_ (..), - DecidablyHasInverses, - tryInvert#, + DecidablyHasInverses (..), tryInvert, + DecidablyHasUndos, + tryUndo#, + tryUndo, DecidablyHasNegations, tryNegate#, tryNegate, @@ -121,30 +126,33 @@ module Lude.Algebra.Magma ( tryRecip, -- * Groups - IsGroup_, - IsGroup, + IsGroupWith, cancelL, + cancelR, + invert, + IsGroup, + stripL, -- TODO: Rename the conflicting (\\) -- (\\), - cancelR, + stripR, (//), - invert, + undo, IsAddGroup, - subtractL, - subtractR, + subL, + subR, subtract, sub, (-), negate, IsMulGroup, - divideByL, - divideByR, + divL, + divR, (/), - divideBy, + div, recip, -- * Commutativity - Commutative_, + HasCommutative, Commutative, AddCommutative, MulCommutative, @@ -178,9 +186,6 @@ import Lude.Function import Lude.Haskell import Lude.Maybe --- TODO: The "magma" terminology is a bit wrong/misleading for the ring-like --- structures. - -- TODO: Break this up. -- TODO: We should somehow connect these to the categorical abstractions, so @@ -219,411 +224,449 @@ import Lude.Maybe -------------------------------------------------------------------------------- -data MagmaB :: Brand -type MagmaK = OpenKind MagmaB +data MagmaOpB :: Brand --- The three standard magma tags. -data Combinative :: MagmaK -data Additive :: MagmaK -data Multiplicative :: MagmaK +-- | The `OpenKind` of magma operations +-- +-- We index `MagmaClass`es by `MagmaOpK` to enable working generically over +-- magmas that differ only in notation. +-- +-- Lude has three standard magma operations: +-- `Combination` (generic), `Addition`, and `Multiplication`. +type MagmaOpK = OpenKind MagmaOpB + +data Combination :: MagmaOpK +data Addition :: MagmaOpK +data Multiplication :: MagmaOpK -------------------------------------------------------------------------------- -- Private Util -type MagmaClass_ :: Kind -type MagmaClass_ = MagmaK -> MagmaClass +type AlgebraClass :: Kind +type AlgebraClass = forall {r :: Repr}. Type# r -> Constraint type MagmaClass :: Kind -type MagmaClass = forall {r :: Repr}. Type# r -> Constraint +type MagmaClass = MagmaOpK -> AlgebraClass + +type NullaryOp :: AlgebraClass -> Type +type NullaryOp c = forall {r :: Repr} (a :: Type# r). (c a) => a + +type PartialUnaryOp :: AlgebraClass -> Type +type PartialUnaryOp c = forall {r :: Repr} (a :: Type# r). (c a, Partial) => Endo a -type UnaryOp :: MagmaClass -> Type +type UnaryOp :: AlgebraClass -> Type type UnaryOp c = forall {r :: Repr} (a :: Type# r). (c a) => Endo a -type UnaryOpMaybe# :: MagmaClass -> Type +type UnaryOpMaybe# :: AlgebraClass -> Type type UnaryOpMaybe# c = forall {r :: Repr} (a :: Type# r). (c a) => a -> Maybe# a -type UnaryOpMaybe :: MagmaClass -> Type +type UnaryOpMaybe :: AlgebraClass -> Type type UnaryOpMaybe c = forall (a :: Type). (c a) => a -> Maybe a -type BinaryOp :: MagmaClass -> Type +type PartialBinaryOp :: AlgebraClass -> Type +type PartialBinaryOp c = forall {r :: Repr} (a :: Type# r). (c a, Partial) => Biendo a + +type BinaryOp :: AlgebraClass -> Type type BinaryOp c = forall {r :: Repr} (a :: Type# r). (c a) => Biendo a -type BinaryOpMaybe# :: MagmaClass -> Type +type BinaryOpMaybe# :: AlgebraClass -> Type type BinaryOpMaybe# c = forall {r :: Repr} (a :: Type# r). (c a) => a -> a -> Maybe# a -type BinaryOpMaybe :: MagmaClass -> Type +type BinaryOpMaybe :: AlgebraClass -> Type type BinaryOpMaybe c = forall (a :: Type). (c a) => a -> a -> Maybe a -type Comm :: Endo MagmaClass_ -class (c this a, Commutative_ this a) => Comm c this (a :: Type# r) -instance forall (c :: MagmaClass_) (this :: MagmaK) (r :: Repr) (a :: Type# r). (c this a, Commutative_ this a) => Comm c this a +type Comm :: Endo MagmaClass +class (c op a, HasCommutative op a) => Comm c op (a :: Type# r) +instance forall (c :: MagmaClass) (op :: MagmaOpK) (r :: Repr) (a :: Type# r). (c op a, HasCommutative op a) => Comm c op a -------------------------------------------------------------------------------- -- TODO: Remove Functional# superclass? We currently require it for some -- generic definitions, but we should probably allow any representation. --- | Semigroup +-- | `MagmaOpK`-indexed semigroups -- --- __Laws:__ --- - /@combine@ is associative:/ @(x ⋄ y) ⋄ z = x ⋄ (y ⋄ z)@ -type IsSemigroup_ :: MagmaClass_ -class (Functional# r) => IsSemigroup_ this (a :: Type# r) where - combine_ :: For this (Biendo a) - -type IsSemigroup = IsSemigroup_ Combinative :: MagmaClass -combine, (<>), (⋄) :: forall {r :: Repr} (a :: Type# r). (IsSemigroup a) => Biendo a -combine = combine_ Combinative +-- __Laws__ (in terms of `IsSemigroup`): +-- - /`combine` is associative:/ @(x ⋄ y) ⋄ z = x ⋄ (y ⋄ z)@ +type IsSemigroupWith :: MagmaClass +class (Functional# r) => IsSemigroupWith op (a :: Type# r) where + operation :: For op (Biendo a) + +type IsSemigroup = IsSemigroupWith Combination :: AlgebraClass +combine, (<>), (⋄) :: BinaryOp IsSemigroup +combine = operation Combination (<>) = combine (⋄) = combine infixl 5 <>, ⋄ -type IsAddSemigroup = IsSemigroup_ Additive :: MagmaClass -add, (+) :: forall {r :: Repr} (a :: Type# r). (IsAddSemigroup a) => Biendo a -add = combine_ Additive +type IsAddSemigroup = IsSemigroupWith Addition :: AlgebraClass +add, (+) :: BinaryOp IsAddSemigroup +add = operation Addition (+) = add infixl 6 + -type IsMulSemigroup = IsSemigroup_ Multiplicative :: MagmaClass -mul, (*) :: forall {r :: Repr} (a :: Type# r). (IsMulSemigroup a) => Biendo a -mul = combine_ Multiplicative +type IsMulSemigroup = IsSemigroupWith Multiplication :: AlgebraClass +mul, (*) :: BinaryOp IsMulSemigroup +mul = operation Multiplication (*) = mul infixl 7 * -------------------------------------------------------------------------------- --- TODO: Names suck here - --- | Semigroup with computable left cancellation for left-cancellable elements +-- | `MagmaOpK`-indexed semigroups with computable left cancellation for +-- left-cancellable elements -- --- __Laws:__ +-- __Laws__ (in terms of `PartiallyStrippableL`): -- - /Partial left cancellation:/ if @x@ is left-cancellative, then @(x \\!) ∘ (x ⋄)@ = @identity@ -- --- We don't specify @(x \\!)@ on elements outside the image of @(x ⋄)@. +-- We don't specify @(x \\!)@ on elements outside the image of @(x ⋄)@, nor do +-- we specify the behavior for non-left-cancellative @x@. -- --- Typically, monoids should also implement `PartiallyHasInverses_` -type PartiallyCancellableL_ :: MagmaClass_ -class (IsSemigroup_ this a) => PartiallyCancellableL_ this (a :: Type# r) where - cancelL'_ :: For this (Biendo a) +-- Typically, monoids should also implement `PartiallyHasInverses`. +type PartiallyCancellableL :: MagmaClass +class (IsSemigroupWith op a) => PartiallyCancellableL op (a :: Type# r) where + pcancelL :: For op ((Partial) => Biendo a) --- | Semigroup with computable right cancellation for right-cancellable elements +-- | `MagmaOpK`-indexed semigroups with computable right cancellation for +-- right-cancellable elements -- --- __Laws:__ +-- __Laws__ (in terms of `PartiallyStrippableR`): -- - /Partial right cancellation:/ if @x@ is right-cancellative, then @(//! x) ∘ (⋄ x)@ = @identity@ -- --- We don't specify @(//! x)@ on elements outside the image of @(⋄ x)@. +-- We don't specify @(//! x)@ on elements outside the image of @(⋄ x)@, nor do +-- we specify the behavior for non-right-cancellative @x@. -- --- Typically, monoids should also implement `PartiallyHasInverses_` -type PartiallyCancellableR_ :: MagmaClass_ -class (IsSemigroup_ this a) => PartiallyCancellableR_ this (a :: Type# r) where - cancelR'_ :: For this (Biendo a) - --- | Commutative semigroup with computable cancellation for cancellable elements -type PartiallyCancellable_ :: MagmaClass_ -class (Commutative_ this a, PartiallyCancellableL_ this a, PartiallyCancellableR_ this a) => PartiallyCancellable_ this (a :: Type# r) - -instance (Commutative_ this a, PartiallyCancellableL_ this a, PartiallyCancellableR_ this a) => PartiallyCancellable_ this (a :: Type# r) - -type PartiallyCancellableL = PartiallyCancellableL_ Combinative :: MagmaClass -cancelL', (\\!) :: BinaryOp PartiallyCancellableL -cancelL' = cancelL'_ Combinative -(\\!) = cancelL' +-- Typically, monoids should also implement `PartiallyHasInverses`. +type PartiallyCancellableR :: MagmaClass +class (IsSemigroupWith op a) => PartiallyCancellableR op (a :: Type# r) where + pcancelR :: For op ((Partial) => Biendo a) + +-- | `MagmaOpK`-indexed commutative semigroups with computable cancellation for +-- cancellable elements +type PartiallyCancellable :: MagmaClass +class (HasCommutative op a, PartiallyCancellableL op a, PartiallyCancellableR op a) => PartiallyCancellable op (a :: Type# r) + +instance (HasCommutative op a, PartiallyCancellableL op a, PartiallyCancellableR op a) => PartiallyCancellable op (a :: Type# r) + +type PartiallyStrippableL = PartiallyCancellableL Combination :: AlgebraClass +pstripL, (\\!) :: PartialBinaryOp PartiallyStrippableL +pstripL = pcancelL Combination +(\\!) = pstripL infixr 5 \\! -type PartiallyCancellableR = PartiallyCancellableR_ Combinative :: MagmaClass -cancelR', (//!) :: BinaryOp PartiallyCancellableR -cancelR' = cancelR'_ Combinative -(//!) = flip cancelR' +type PartiallyStrippableR = PartiallyCancellableR Combination :: AlgebraClass +pstripR, (//!) :: PartialBinaryOp PartiallyStrippableR +pstripR = pcancelR Combination +(//!) = pstripR infixl 5 //! -type PartiallyCancellable = PartiallyCancellable_ Combinative :: MagmaClass -cancel' :: BinaryOp PartiallyCancellable -cancel' = cancelR' +type PartiallyStrippable = PartiallyCancellable Combination :: AlgebraClass +pstrip :: PartialBinaryOp PartiallyStrippable +pstrip = pstripR -type PartiallySubtractableL = PartiallyCancellableL_ Additive :: MagmaClass -subtractL' :: BinaryOp PartiallySubtractableL -subtractL' = cancelL'_ Additive +type PartiallySubtractableL = PartiallyCancellableL Addition :: AlgebraClass +psubL :: PartialBinaryOp PartiallySubtractableL +psubL = pcancelL Addition -type PartiallySubtractableR = PartiallyCancellableR_ Additive :: MagmaClass -subtractR' :: BinaryOp PartiallySubtractableR -subtractR' = cancelR'_ Additive +type PartiallySubtractableR = PartiallyCancellableR Addition :: AlgebraClass +psubR :: PartialBinaryOp PartiallySubtractableR +psubR = pcancelR Addition -- NOTE: There're no standard symbols for left/right-subtraction, because -- usually one assumes additive operations are commutative. So we just -- require commutativity for the subtraction symbols. -type PartiallySubtractable = PartiallyCancellable_ Additive :: MagmaClass -subtract', sub', (-!) :: BinaryOp PartiallySubtractable -subtract' = subtractR' -sub' = flip subtract' -(-!) = sub' +type PartiallySubtractable = PartiallyCancellable Addition :: AlgebraClass +psubtract, psub, (-!) :: PartialBinaryOp PartiallySubtractable +psubtract = psubL +psub = psubR +(-!) = psub infixl 6 -! -type PartiallyDividableL = PartiallyCancellableL_ Multiplicative :: MagmaClass -divideByL', (\!) :: BinaryOp PartiallyDividableL -divideByL' = cancelL'_ Multiplicative -(\!) = divideByL' +type PartiallyDividableL = PartiallyCancellableL Multiplication :: AlgebraClass +pdivL, (\!) :: PartialBinaryOp PartiallyDividableL +pdivL = pcancelL Multiplication +(\!) = pdivL infixr 7 \! -type PartiallyDividableR = PartiallyCancellableR_ Multiplicative :: MagmaClass -divideByR', (/!) :: BinaryOp PartiallyDividableR -divideByR' = cancelR'_ Multiplicative -(/!) = flip divideByR' +type PartiallyDividableR = PartiallyCancellableR Multiplication :: AlgebraClass +pdivR, (/!) :: PartialBinaryOp PartiallyDividableR +pdivR = pcancelR Multiplication +(/!) = pdivR infixl 7 /! -type PartiallyDividable = PartiallyCancellable_ Multiplicative :: MagmaClass -divideBy' :: BinaryOp PartiallyDividable -divideBy' = divideByR' +type PartiallyDividable = PartiallyCancellable Multiplication :: AlgebraClass +pdiv :: PartialBinaryOp PartiallyDividable +pdiv = pdivR -------------------------------------------------------------------------------- --- | Semigroup with "decidable left cancellation" (i.e., decidable --- left-cancellability and decidable images of left-combination with +-- | `MagmaOpK`-indexed semigroups with "decidable left cancellation" (i.e., +-- decidable left-cancellability and decidable images of left-operation with -- left-cancellable elements) -- --- __Laws:__ +-- __Laws__ (in terms of `DecidablyStrippableL`): -- - /Decidable left cancellation:/ if @x@ is left-cancellative and @y@ -- factors (necessarily uniquely) as @y = x ⋄ z@, then @x \\? y@ = -- @Just z@; otherwise, @x \\? y@ = @Nothing@ -- --- Typically, monoids should also implement `DecidablyHasInverses_` -type DecidablyCancellableL_ :: MagmaClass_ -class (PartiallyCancellableL_ this a) => DecidablyCancellableL_ this (a :: Type# r) where - tryCancelL_# :: For this (a -> a -> Maybe# a) +-- Typically, monoids should also implement `DecidablyHasInverses`. +type DecidablyCancellableL :: MagmaClass +class (PartiallyCancellableL op a) => DecidablyCancellableL op (a :: Type# r) where + tryCancelL# :: For op (a -> a -> Maybe# a) + +tryCancelL :: forall (op :: MagmaOpK) -> BinaryOpMaybe (DecidablyCancellableL op) +tryCancelL op = coerce (tryCancelL# op) --- | Semigroup with "decidable right cancellation" (i.e., decidable --- right-cancellability and decidable images of right-combination with +-- | `MagmaOpK`-indexed semigroups with "decidable right cancellation" (i.e., +-- decidable right-cancellability and decidable images of right-operation with -- right-cancellable elements) -- --- __Laws:__ +-- __Laws__ (in terms of `DecidablyStrippableR`): -- - /Decidable right cancellation:/ if @x@ is right-cancellative and @y@ -- factors (necessarily uniquely) as @y = z ⋄ x@, then @y //? x@ = -- @Just z@; otherwise, @y //? x@ = @Nothing@ -- --- Typically, monoids should also implement `DecidablyHasInverses_` -type DecidablyCancellableR_ :: MagmaClass_ -class (PartiallyCancellableR_ this a) => DecidablyCancellableR_ this (a :: Type# r) where - tryCancelR_# :: For this (a -> a -> Maybe# a) - --- | Commutative semigroup with "decidable cancellation" (i.e., decidable --- cancellability and decidable images of combination with cancellable elements) -type DecidablyCancellable_ :: MagmaClass_ -class (Commutative_ this a, DecidablyCancellableL_ this a, DecidablyCancellableR_ this a) => DecidablyCancellable_ this (a :: Type# r) - -instance (Commutative_ this a, DecidablyCancellableL_ this a, DecidablyCancellableR_ this a) => DecidablyCancellable_ this (a :: Type# r) - -type DecidablyCancellableL = DecidablyCancellableL_ Combinative :: MagmaClass -tryCancelL#, (\\?#) :: BinaryOpMaybe# DecidablyCancellableL -tryCancelL, (\\?) :: BinaryOpMaybe DecidablyCancellableL -tryCancelL# = tryCancelL_# Combinative -(\\?#) = tryCancelL# -tryCancelL = coerce tryCancelL# -(\\?) = tryCancelL +-- Typically, monoids should also implement `DecidablyHasInverses`. +type DecidablyCancellableR :: MagmaClass +class (PartiallyCancellableR op a) => DecidablyCancellableR op (a :: Type# r) where + tryCancelR# :: For op (a -> a -> Maybe# a) + +tryCancelR :: forall (op :: MagmaOpK) -> BinaryOpMaybe (DecidablyCancellableR op) +tryCancelR op = coerce (tryCancelR# op) + +-- | `MagmaOpK`-indexed commutative semigroup with "decidable cancellation" +-- (i.e., decidable cancellability and decidable images of operation with +-- cancellable elements) +type DecidablyCancellable :: MagmaClass +class (HasCommutative op a, DecidablyCancellableL op a, DecidablyCancellableR op a) => DecidablyCancellable op (a :: Type# r) + +instance (HasCommutative op a, DecidablyCancellableL op a, DecidablyCancellableR op a) => DecidablyCancellable op (a :: Type# r) + +type DecidablyStrippableL = DecidablyCancellableL Combination :: AlgebraClass +tryStripL#, (\\?#) :: BinaryOpMaybe# DecidablyStrippableL +tryStripL, (\\?) :: BinaryOpMaybe DecidablyStrippableL +tryStripL# = tryCancelL# Combination +(\\?#) = tryStripL# +tryStripL = coerce tryStripL# +(\\?) = tryStripL infix 5 \\?#, \\? -type DecidablyCancellableR = DecidablyCancellableR_ Combinative :: MagmaClass -tryCancelR#, (//?#) :: BinaryOpMaybe# DecidablyCancellableR -tryCancelR, (//?) :: BinaryOpMaybe DecidablyCancellableR -tryCancelR# = tryCancelR_# Combinative -(//?#) = flip tryCancelR# -tryCancelR = coerce tryCancelR# -(//?) = flip tryCancelR +type DecidablyStrippableR = DecidablyCancellableR Combination :: AlgebraClass +tryStripR#, (//?#) :: BinaryOpMaybe# DecidablyStrippableR +tryStripR, (//?) :: BinaryOpMaybe DecidablyStrippableR +tryStripR# = tryCancelR# Combination +(//?#) = tryStripR# +tryStripR = coerce tryStripR# +(//?) = tryStripR infix 5 //?#, //? -type DecidablyCancellable = DecidablyCancellable_ Combinative :: MagmaClass -tryCancel# :: BinaryOpMaybe# DecidablyCancellable -tryCancel :: BinaryOpMaybe DecidablyCancellable -tryCancel# = tryCancelR# -tryCancel = tryCancelR - -type DecidablySubtractableL = DecidablyCancellableL_ Additive :: MagmaClass -trySubtractL# :: BinaryOpMaybe# DecidablySubtractableL -trySubtractL :: BinaryOpMaybe DecidablySubtractableL -trySubtractL# = tryCancelL_# Additive -trySubtractL = coerce trySubtractL# - -type DecidablySubtractableR = DecidablyCancellableR_ Additive :: MagmaClass -trySubtractR# :: BinaryOpMaybe# DecidablySubtractableR -trySubtractR :: BinaryOpMaybe DecidablySubtractableR -trySubtractR# = tryCancelR_# Additive -trySubtractR = coerce trySubtractR# - -type DecidablySubtractable = DecidablyCancellable_ Additive :: MagmaClass -trySubtract# :: BinaryOpMaybe# DecidablySubtractable -trySubtract :: BinaryOpMaybe DecidablySubtractable -trySubtract# = trySubtractR# -trySubtract = trySubtractR - -type DecidablyDividableL = DecidablyCancellableL_ Multiplicative :: MagmaClass -tryDivideByL#, (\?#) :: BinaryOpMaybe# DecidablyDividableL -tryDivideByL, (\?) :: BinaryOpMaybe DecidablyDividableL -tryDivideByL# = tryCancelL_# Multiplicative -(\?#) = tryDivideByL# -tryDivideByL = coerce tryDivideByL# -(\?) = tryDivideByL +type DecidablyStrippable = DecidablyCancellable Combination :: AlgebraClass +tryStrip# :: BinaryOpMaybe# DecidablyStrippable +tryStrip :: BinaryOpMaybe DecidablyStrippable +tryStrip# = tryStripR# +tryStrip = tryStripR + +type DecidablySubtractableL = DecidablyCancellableL Addition :: AlgebraClass +trySubL# :: BinaryOpMaybe# DecidablySubtractableL +trySubL :: BinaryOpMaybe DecidablySubtractableL +trySubL# = tryCancelL# Addition +trySubL = coerce trySubL# + +type DecidablySubtractableR = DecidablyCancellableR Addition :: AlgebraClass +trySubR# :: BinaryOpMaybe# DecidablySubtractableR +trySubR :: BinaryOpMaybe DecidablySubtractableR +trySubR# = tryCancelR# Addition +trySubR = coerce trySubR# + +type DecidablySubtractable = DecidablyCancellable Addition :: AlgebraClass +trySub#, (-?#) :: BinaryOpMaybe# DecidablySubtractable +trySub, (-?) :: BinaryOpMaybe DecidablySubtractable +trySub# = trySubR# +(-?#) = trySub# +trySub = trySubR +(-?) = trySub +infix 6 -?#, -? + +type DecidablyDividableL = DecidablyCancellableL Multiplication :: AlgebraClass +tryDivL#, (\?#) :: BinaryOpMaybe# DecidablyDividableL +tryDivL, (\?) :: BinaryOpMaybe DecidablyDividableL +tryDivL# = tryCancelL# Multiplication +(\?#) = tryDivL# +tryDivL = coerce tryDivL# +(\?) = tryDivL infix 7 \?#, \? -type DecidablyDividableR = DecidablyCancellableR_ Multiplicative :: MagmaClass -tryDivideByR#, (/?#) :: BinaryOpMaybe# DecidablyDividableR -tryDivideByR, (/?) :: BinaryOpMaybe DecidablyDividableR -tryDivideByR# = tryCancelR_# Multiplicative -(/?#) = flip tryDivideByR# -tryDivideByR = coerce tryDivideByR# -(/?) = flip tryDivideByR +type DecidablyDividableR = DecidablyCancellableR Multiplication :: AlgebraClass +tryDivR#, (/?#) :: BinaryOpMaybe# DecidablyDividableR +tryDivR, (/?) :: BinaryOpMaybe DecidablyDividableR +tryDivR# = tryCancelR# Multiplication +(/?#) = tryDivR# +tryDivR = coerce tryDivR# +(/?) = tryDivR infix 7 /?#, /? -type DecidablyDividable = DecidablyCancellable_ Multiplicative :: MagmaClass -tryDivideBy# :: BinaryOpMaybe# DecidablyDividable -tryDivideBy :: BinaryOpMaybe DecidablyDividable -tryDivideBy# = tryDivideByR# -tryDivideBy = tryDivideByR +type DecidablyDividable = DecidablyCancellable Multiplication :: AlgebraClass +tryDiv# :: BinaryOpMaybe# DecidablyDividable +tryDiv :: BinaryOpMaybe DecidablyDividable +tryDiv# = tryDivR# +tryDiv = tryDivR -------------------------------------------------------------------------------- --- | Monoid +-- | `MagmaOpK`-indexed monoids -- --- __Laws:__ --- - /@neutral@ is a (left and right) identity element:/ @neutral ⋄ x = x = x ⋄ neutral@ -type IsMonoid_ :: MagmaClass_ -class (IsSemigroup_ this a) => IsMonoid_ this (a :: Type# r) where - neutral_ :: For this a +-- __Laws__ (in terms of `IsMonoid`): +-- - /@nil@ is a (left and right) identity element:/ @nil ⋄ x = x = x ⋄ nil@ +type IsMonoidWith :: MagmaClass +class (IsSemigroupWith op a) => IsMonoidWith op (a :: Type# r) where + neutral :: For op a -type IsMonoid = IsMonoid_ Combinative :: MagmaClass -neutral :: forall {r :: Repr} (a :: Type# r). (IsMonoid a) => a -neutral = neutral_ Combinative +type IsMonoid = IsMonoidWith Combination :: AlgebraClass +nil :: NullaryOp IsMonoid +nil = neutral Combination -type IsAddMonoid = IsMonoid_ Additive :: MagmaClass -zero :: forall {r :: Repr} (a :: Type# r). (IsAddMonoid a) => a -zero = neutral_ Additive +type IsAddMonoid = IsMonoidWith Addition :: AlgebraClass +zero :: NullaryOp IsAddMonoid +zero = neutral Addition -type IsMulMonoid = IsMonoid_ Multiplicative :: MagmaClass -one :: forall {r :: Repr} (a :: Type# r). (IsMulMonoid a) => a -one = neutral_ Multiplicative +type IsMulMonoid = IsMonoidWith Multiplication :: AlgebraClass +one :: NullaryOp IsMulMonoid +one = neutral Multiplication -------------------------------------------------------------------------------- -- NOTE: One-sided (left/right) inverses are noncanonical (and apparently not -- very useful, anyway), so we only model two-sided inverses. --- | Monoid with computable inverses for invertible elements +-- | `MagmaOpK`-indexed monoids with computable inverses for invertible elements -- --- __Laws:__ --- - /Partial inversion:/ if @x@ has inverse @y@, then @invert' x = y@ +-- __Laws__ (in terms of `PartiallyHasUndos`): +-- - /Partial inversion:/ if @x@ has inverse @y@, then @pundo x = y@ -- --- We don't specify @invert'@ on non-invertible elements. -type PartiallyHasInverses_ :: MagmaClass_ -class (IsMonoid_ this a) => PartiallyHasInverses_ this (a :: Type# r) where - invert'_ :: For this (Endo a) +-- We don't specify @pundo@ on non-invertible elements. +type PartiallyHasInverses :: MagmaClass +class (IsMonoidWith op a) => PartiallyHasInverses op (a :: Type# r) where + pinvert :: For op ((Partial) => Endo a) -type PartiallyHasInverses = PartiallyHasInverses_ Combinative :: MagmaClass -invert' :: UnaryOp PartiallyHasInverses -invert' = invert'_ Combinative +type PartiallyHasUndos = PartiallyHasInverses Combination :: AlgebraClass +pundo :: PartialUnaryOp PartiallyHasUndos +pundo = pinvert Combination -type PartiallyHasNegations = PartiallyHasInverses_ Additive :: MagmaClass -negate' :: UnaryOp PartiallyHasNegations -negate' = invert'_ Additive +type PartiallyHasNegations = PartiallyHasInverses Addition :: AlgebraClass +pnegate :: PartialUnaryOp PartiallyHasNegations +pnegate = pinvert Addition -type PartiallyHasReciprocals = PartiallyHasInverses_ Multiplicative :: MagmaClass -recip' :: UnaryOp PartiallyHasReciprocals -recip' = invert'_ Multiplicative +type PartiallyHasReciprocals = PartiallyHasInverses Multiplication :: AlgebraClass +precip :: PartialUnaryOp PartiallyHasReciprocals +precip = pinvert Multiplication -------------------------------------------------------------------------------- --- | Monoid with decidable invertibility and computable inverses for invertible --- elements +-- | `MagmaOpK`-indexed monoids with decidable invertibility and computable +-- inverses for invertible elements -- --- __Laws:__ --- - /Decidable inversion:/ if @x@ has inverse @y@, then @tryInvert x@ = --- @Just y@; otherwise, @tryInvert x = Nothing@ -type DecidablyHasInverses_ :: MagmaClass_ -class (PartiallyHasInverses_ this a) => DecidablyHasInverses_ this (a :: Type# r) where - tryInvert_# :: For this (a -> Maybe# a) - -type DecidablyHasInverses = DecidablyHasInverses_ Combinative :: MagmaClass -tryInvert# :: UnaryOpMaybe# DecidablyHasInverses -tryInvert :: UnaryOpMaybe DecidablyHasInverses -tryInvert# = tryInvert_# Combinative -tryInvert = coerce tryInvert# - -type DecidablyHasNegations = DecidablyHasInverses_ Additive :: MagmaClass +-- __Laws__ (in terms of `DecidablyHasUndos`): +-- - /Decidable inversion:/ if @x@ has inverse @y@, then @tryUndo x@ = +-- @Just y@; otherwise, @tryUndo x = Nothing@ +type DecidablyHasInverses :: MagmaClass +class (PartiallyHasInverses op a) => DecidablyHasInverses op (a :: Type# r) where + tryInvert# :: For op (a -> Maybe# a) + +tryInvert :: forall (op :: MagmaOpK) -> UnaryOpMaybe (DecidablyHasInverses op) +tryInvert op = coerce (tryInvert# op) + +type DecidablyHasUndos = DecidablyHasInverses Combination :: AlgebraClass +tryUndo# :: UnaryOpMaybe# DecidablyHasUndos +tryUndo :: UnaryOpMaybe DecidablyHasUndos +tryUndo# = tryInvert# Combination +tryUndo = coerce tryUndo# + +type DecidablyHasNegations = DecidablyHasInverses Addition :: AlgebraClass tryNegate# :: UnaryOpMaybe# DecidablyHasNegations tryNegate :: UnaryOpMaybe DecidablyHasNegations -tryNegate# = tryInvert_# Additive +tryNegate# = tryInvert# Addition tryNegate = coerce tryNegate# -type DecidablyHasReciprocals = DecidablyHasInverses_ Multiplicative :: MagmaClass +type DecidablyHasReciprocals = DecidablyHasInverses Multiplication :: AlgebraClass tryRecip# :: UnaryOpMaybe# DecidablyHasReciprocals tryRecip :: UnaryOpMaybe DecidablyHasReciprocals -tryRecip# = tryInvert_# Multiplicative +tryRecip# = tryInvert# Multiplication tryRecip = coerce tryRecip# -------------------------------------------------------------------------------- --- | Group +-- | `MagmaOpK`-indexed groups -- --- __Laws:__ --- - /Every element is invertible:/ @isJust (tryInvert x)@ = @True@ -type IsGroup_ :: MagmaClass_ -class (DecidablyHasInverses_ this a, DecidablyCancellableL_ this a, DecidablyCancellableR_ this a) => IsGroup_ this (a :: Type# r) - -type IsGroup = IsGroup_ Combinative :: MagmaClass -cancelL, (\\), cancelR, (//) :: BinaryOp IsGroup -invert :: UnaryOp IsGroup -cancelL = cancelL' -(\\) = (\\!) -cancelR = cancelR' -(//) = (//!) -invert = invert' +-- __Laws__ (in terms of `IsGroup`): +-- - /Every element is invertible:/ @isJust (tryUndo x)@ = @True@ +type IsGroupWith :: MagmaClass +class (DecidablyHasInverses op a, DecidablyCancellableL op a, DecidablyCancellableR op a) => IsGroupWith op (a :: Type# r) + +cancelL, cancelR :: forall (op :: MagmaOpK) -> BinaryOp (IsGroupWith op) +invert :: forall (op :: MagmaOpK) -> UnaryOp (IsGroupWith op) +cancelL op = unsafe_partial (pcancelL op) +cancelR op = unsafe_partial (pcancelR op) +invert op = unsafe_partial (pinvert op) + +type IsGroup = IsGroupWith Combination :: AlgebraClass +stripL, (\\), stripR, (//) :: BinaryOp IsGroup +undo :: UnaryOp IsGroup +stripL = unsafe_partial pstripL +(\\) = unsafe_partial (\\!) +stripR = unsafe_partial pstripR +(//) = unsafe_partial (//!) +undo = unsafe_partial pundo infixr 5 \\ infixl 5 // -type IsAddGroup = IsGroup_ Additive :: MagmaClass -subtractL, subtractR :: BinaryOp IsAddGroup +type IsAddGroup = IsGroupWith Addition :: AlgebraClass +subL, subR :: BinaryOp IsAddGroup subtract, sub, (-) :: BinaryOp IsCommAddGroup negate :: UnaryOp IsAddGroup -subtractL = subtractL' -subtractR = subtractR' -subtract = subtract' -sub = sub' -(-) = (-!) -negate = negate' +subL = unsafe_partial psubL +subR = unsafe_partial psubR +subtract = unsafe_partial psubtract +sub = unsafe_partial psub +(-) = unsafe_partial (-!) +negate = unsafe_partial pnegate infixl 6 - -type IsMulGroup = IsGroup_ Multiplicative :: MagmaClass -divideByL, divideByR, (/) :: BinaryOp IsMulGroup -- NOTE: (\) is reserved in Haskell :( -divideBy :: BinaryOp IsCommMulGroup +type IsMulGroup = IsGroupWith Multiplication :: AlgebraClass +divL, divR, (/) :: BinaryOp IsMulGroup -- NOTE: (\) is reserved in Haskell :( +div :: BinaryOp IsCommMulGroup recip :: UnaryOp IsMulGroup -divideByL = divideByL' -divideByR = divideByR' -(/) = (/!) -divideBy = divideBy' -recip = recip' +divL = unsafe_partial pdivL +divR = unsafe_partial pdivR +(/) = unsafe_partial (/!) +div = unsafe_partial pdiv +recip = unsafe_partial precip infixl 7 / -------------------------------------------------------------------------------- --- | Commutative semigroup +-- | Commutative semigroups -- --- __Laws:__ +-- __Laws__ (in terms of `IsCommSemigroup`): -- - /@combine@ is commutative:/ @x ⋄ y = y ⋄ x@ -type Commutative_ :: MagmaClass_ -class (IsSemigroup_ this a) => Commutative_ this (a :: Type# r) +type HasCommutative :: MagmaClass +class (IsSemigroupWith op a) => HasCommutative op (a :: Type# r) -type Commutative = Commutative_ Combinative :: MagmaClass -type AddCommutative = Commutative_ Additive :: MagmaClass -type MulCommutative = Commutative_ Multiplicative :: MagmaClass +type Commutative = HasCommutative Combination :: AlgebraClass +type AddCommutative = HasCommutative Addition :: AlgebraClass +type MulCommutative = HasCommutative Multiplication :: AlgebraClass -type IsCommSemigroup = Comm IsSemigroup_ Combinative :: MagmaClass -type IsCommAddSemigroup = Comm IsSemigroup_ Additive :: MagmaClass -type IsCommMulSemigroup = Comm IsSemigroup_ Multiplicative :: MagmaClass +type IsCommSemigroup = Comm IsSemigroupWith Combination :: AlgebraClass +type IsCommAddSemigroup = Comm IsSemigroupWith Addition :: AlgebraClass +type IsCommMulSemigroup = Comm IsSemigroupWith Multiplication :: AlgebraClass -type IsCommMonoid = Comm IsMonoid_ Combinative :: MagmaClass -type IsCommAddMonoid = Comm IsMonoid_ Additive :: MagmaClass -type IsCommMulMonoid = Comm IsMonoid_ Multiplicative :: MagmaClass +type IsCommMonoid = Comm IsMonoidWith Combination :: AlgebraClass +type IsCommAddMonoid = Comm IsMonoidWith Addition :: AlgebraClass +type IsCommMulMonoid = Comm IsMonoidWith Multiplication :: AlgebraClass -type IsCommGroup = Comm IsGroup_ Combinative :: MagmaClass -type IsCommAddGroup = Comm IsGroup_ Additive :: MagmaClass -type IsCommMulGroup = Comm IsGroup_ Multiplicative :: MagmaClass +type IsCommGroup = Comm IsGroupWith Combination :: AlgebraClass +type IsCommAddGroup = Comm IsGroupWith Addition :: AlgebraClass +type IsCommMulGroup = Comm IsGroupWith Multiplication :: AlgebraClass -------------------------------------------------------------------------------- @@ -633,24 +676,24 @@ type IsCommMulGroup = Comm IsGroup_ Multiplicative :: MagmaClass -- TODO: DecidableZero for decidable division rings (and fields)? -type IsSemiring :: MagmaClass +type IsSemiring :: AlgebraClass class (IsCommAddMonoid a, IsMulMonoid a) => IsSemiring (a :: Type# r) -type IsCommSemiring :: MagmaClass +type IsCommSemiring :: AlgebraClass class (IsSemiring a, MulCommutative a) => IsCommSemiring (a :: Type# r) instance (IsSemiring a, MulCommutative a) => IsCommSemiring (a :: Type# r) -type IsRing :: MagmaClass +type IsRing :: AlgebraClass class (IsSemiring a, IsAddGroup a) => IsRing (a :: Type# r) -type IsCommRing :: MagmaClass +type IsCommRing :: AlgebraClass class (IsRing a, MulCommutative a) => IsCommRing (a :: Type# r) instance (IsRing a, MulCommutative a) => IsCommRing (a :: Type# r) -type IsDivisionRing :: MagmaClass +type IsDivisionRing :: AlgebraClass class (IsRing a, PartiallyDividableL a, PartiallyDividableR a, PartiallyHasReciprocals a) => IsDivisionRing a -type IsField :: MagmaClass +type IsField :: AlgebraClass class (IsDivisionRing a, MulCommutative a) => IsField a instance (IsDivisionRing a, MulCommutative a) => IsField a @@ -662,23 +705,23 @@ baseZero = 0 where fromInteger = Base.fromInteger baseOne :: (Base.Num a) => a baseOne = 1 where fromInteger = Base.fromInteger -instance (Base.Num a) => IsSemigroup_ Additive (BaseInterop a) where combine_ _ = coerce (Base.+) -instance (Base.Num a) => PartiallyCancellableL_ Additive (BaseInterop a) where cancelL'_ _ = coerce Base.subtract -instance (Base.Num a) => DecidablyCancellableL_ Additive (BaseInterop a) where tryCancelL_# _ = coerce $ Just .* Base.subtract -instance (Base.Num a) => PartiallyCancellableR_ Additive (BaseInterop a) where cancelR'_ _ = coerce Base.subtract -instance (Base.Num a) => DecidablyCancellableR_ Additive (BaseInterop a) where tryCancelR_# _ = coerce $ Just .* Base.subtract -instance (Base.Num a) => IsMonoid_ Additive (BaseInterop a) where neutral_ _ = coerce baseZero -instance (Base.Num a) => PartiallyHasInverses_ Additive (BaseInterop a) where invert'_ _ = coerce Base.negate -instance (Base.Num a) => DecidablyHasInverses_ Additive (BaseInterop a) where tryInvert_# _ = coerce $ Just . Base.negate -instance (Base.Num a) => IsGroup_ Additive (BaseInterop a) -instance (Base.Num a) => Commutative_ Additive (BaseInterop a) -instance (Base.Num a) => IsSemigroup_ Multiplicative (BaseInterop a) where combine_ _ = coerce (Base.*) -instance (Base.Num a) => IsMonoid_ Multiplicative (BaseInterop a) where neutral_ _ = coerce baseOne +instance (Base.Num a) => IsSemigroupWith Addition (BaseInterop a) where operation _ = coerce (Base.+) +instance (Base.Num a) => PartiallyCancellableL Addition (BaseInterop a) where pcancelL _ = coerce Base.subtract +instance (Base.Num a) => DecidablyCancellableL Addition (BaseInterop a) where tryCancelL# _ = coerce $ Just .* Base.subtract +instance (Base.Num a) => PartiallyCancellableR Addition (BaseInterop a) where pcancelR _ = coerce (Base.-) +instance (Base.Num a) => DecidablyCancellableR Addition (BaseInterop a) where tryCancelR# _ = coerce $ Just .* (Base.-) +instance (Base.Num a) => IsMonoidWith Addition (BaseInterop a) where neutral _ = coerce baseZero +instance (Base.Num a) => PartiallyHasInverses Addition (BaseInterop a) where pinvert _ = coerce Base.negate +instance (Base.Num a) => DecidablyHasInverses Addition (BaseInterop a) where tryInvert# _ = coerce $ Just . Base.negate +instance (Base.Num a) => IsGroupWith Addition (BaseInterop a) +instance (Base.Num a) => HasCommutative Addition (BaseInterop a) +instance (Base.Num a) => IsSemigroupWith Multiplication (BaseInterop a) where operation _ = coerce (Base.*) +instance (Base.Num a) => IsMonoidWith Multiplication (BaseInterop a) where neutral _ = coerce baseOne instance (Base.Num a) => IsSemiring (BaseInterop a) instance (Base.Num a) => IsRing (BaseInterop a) -instance (Base.Fractional a) => PartiallyCancellableL_ Multiplicative (BaseInterop a) where cancelL'_ _ = coerce \x y -> Base.recip x Base.* y -instance (Base.Fractional a) => PartiallyCancellableR_ Multiplicative (BaseInterop a) where cancelR'_ _ = coerce $ flip (Base./) -instance (Base.Fractional a) => PartiallyHasInverses_ Multiplicative (BaseInterop a) where invert'_ _ = coerce Base.recip +instance (Base.Fractional a) => PartiallyCancellableL Multiplication (BaseInterop a) where pcancelL _ = coerce \x y -> Base.recip x Base.* y +instance (Base.Fractional a) => PartiallyCancellableR Multiplication (BaseInterop a) where pcancelR _ = coerce (Base./) +instance (Base.Fractional a) => PartiallyHasInverses Multiplication (BaseInterop a) where pinvert _ = coerce Base.recip instance (Base.Fractional a) => IsDivisionRing (BaseInterop a) -------------------------------------------------------------------------------- @@ -689,67 +732,67 @@ baseDivNonZero x y = if y Base.== baseZero then Nothing else Just (x Base./ y) baseRecipNonZero :: forall (a :: Type). (Base.Eq a, Base.Fractional a) => a -> Maybe a baseRecipNonZero x = if x Base.== baseZero then Nothing else Just (Base.recip x) -deriving via BaseInterop Natural instance IsSemigroup_ Additive Natural -deriving via BaseInterop Natural instance PartiallyCancellableL_ Additive Natural -instance DecidablyCancellableL_ Additive Natural where tryCancelL_# _ = coerce $ flip Base.minusNaturalMaybe -deriving via BaseInterop Natural instance PartiallyCancellableR_ Additive Natural -instance DecidablyCancellableR_ Additive Natural where tryCancelR_# _ = coerce $ flip Base.minusNaturalMaybe -deriving via BaseInterop Natural instance IsMonoid_ Additive Natural -deriving via BaseInterop Natural instance Commutative_ Additive Natural -deriving via BaseInterop Natural instance IsSemigroup_ Multiplicative Natural -deriving via BaseInterop Natural instance IsMonoid_ Multiplicative Natural -instance Commutative_ Multiplicative Natural +deriving via BaseInterop Natural instance IsSemigroupWith Addition Natural +deriving via BaseInterop Natural instance PartiallyCancellableL Addition Natural +instance DecidablyCancellableL Addition Natural where tryCancelL# _ = coerce $ flip Base.minusNaturalMaybe +deriving via BaseInterop Natural instance PartiallyCancellableR Addition Natural +instance DecidablyCancellableR Addition Natural where tryCancelR# _ = coerce Base.minusNaturalMaybe +deriving via BaseInterop Natural instance IsMonoidWith Addition Natural +deriving via BaseInterop Natural instance HasCommutative Addition Natural +deriving via BaseInterop Natural instance IsSemigroupWith Multiplication Natural +deriving via BaseInterop Natural instance IsMonoidWith Multiplication Natural +instance HasCommutative Multiplication Natural deriving via BaseInterop Natural instance IsSemiring Natural -deriving via BaseInterop Integer instance IsSemigroup_ Additive Integer -deriving via BaseInterop Integer instance PartiallyCancellableL_ Additive Integer -deriving via BaseInterop Integer instance DecidablyCancellableL_ Additive Integer -deriving via BaseInterop Integer instance PartiallyCancellableR_ Additive Integer -deriving via BaseInterop Integer instance DecidablyCancellableR_ Additive Integer -deriving via BaseInterop Integer instance IsMonoid_ Additive Integer -deriving via BaseInterop Integer instance PartiallyHasInverses_ Additive Integer -deriving via BaseInterop Integer instance DecidablyHasInverses_ Additive Integer -deriving via BaseInterop Integer instance IsGroup_ Additive Integer -deriving via BaseInterop Integer instance Commutative_ Additive Integer -deriving via BaseInterop Integer instance IsSemigroup_ Multiplicative Integer -deriving via BaseInterop Integer instance IsMonoid_ Multiplicative Integer -instance Commutative_ Multiplicative Integer +deriving via BaseInterop Integer instance IsSemigroupWith Addition Integer +deriving via BaseInterop Integer instance PartiallyCancellableL Addition Integer +deriving via BaseInterop Integer instance DecidablyCancellableL Addition Integer +deriving via BaseInterop Integer instance PartiallyCancellableR Addition Integer +deriving via BaseInterop Integer instance DecidablyCancellableR Addition Integer +deriving via BaseInterop Integer instance IsMonoidWith Addition Integer +deriving via BaseInterop Integer instance PartiallyHasInverses Addition Integer +deriving via BaseInterop Integer instance DecidablyHasInverses Addition Integer +deriving via BaseInterop Integer instance IsGroupWith Addition Integer +deriving via BaseInterop Integer instance HasCommutative Addition Integer +deriving via BaseInterop Integer instance IsSemigroupWith Multiplication Integer +deriving via BaseInterop Integer instance IsMonoidWith Multiplication Integer +instance HasCommutative Multiplication Integer deriving via BaseInterop Integer instance IsSemiring Integer deriving via BaseInterop Integer instance IsRing Integer -deriving via BaseInterop Rational instance IsSemigroup_ Additive Rational -deriving via BaseInterop Rational instance PartiallyCancellableL_ Additive Rational -deriving via BaseInterop Rational instance DecidablyCancellableL_ Additive Rational -deriving via BaseInterop Rational instance PartiallyCancellableR_ Additive Rational -deriving via BaseInterop Rational instance DecidablyCancellableR_ Additive Rational -deriving via BaseInterop Rational instance IsMonoid_ Additive Rational -deriving via BaseInterop Rational instance PartiallyHasInverses_ Additive Rational -deriving via BaseInterop Rational instance DecidablyHasInverses_ Additive Rational -deriving via BaseInterop Rational instance IsGroup_ Additive Rational -deriving via BaseInterop Rational instance Commutative_ Additive Rational -deriving via BaseInterop Rational instance IsSemigroup_ Multiplicative Rational -deriving via BaseInterop Rational instance IsMonoid_ Multiplicative Rational -instance Commutative_ Multiplicative Rational +deriving via BaseInterop Rational instance IsSemigroupWith Addition Rational +deriving via BaseInterop Rational instance PartiallyCancellableL Addition Rational +deriving via BaseInterop Rational instance DecidablyCancellableL Addition Rational +deriving via BaseInterop Rational instance PartiallyCancellableR Addition Rational +deriving via BaseInterop Rational instance DecidablyCancellableR Addition Rational +deriving via BaseInterop Rational instance IsMonoidWith Addition Rational +deriving via BaseInterop Rational instance PartiallyHasInverses Addition Rational +deriving via BaseInterop Rational instance DecidablyHasInverses Addition Rational +deriving via BaseInterop Rational instance IsGroupWith Addition Rational +deriving via BaseInterop Rational instance HasCommutative Addition Rational +deriving via BaseInterop Rational instance IsSemigroupWith Multiplication Rational +deriving via BaseInterop Rational instance IsMonoidWith Multiplication Rational +instance HasCommutative Multiplication Rational deriving via BaseInterop Rational instance IsSemiring Rational deriving via BaseInterop Rational instance IsRing Rational -deriving via BaseInterop Rational instance PartiallyCancellableL_ Multiplicative Rational -instance DecidablyCancellableL_ Multiplicative Rational where tryCancelL_# _ = coerce $ flip baseDivNonZero -deriving via BaseInterop Rational instance PartiallyCancellableR_ Multiplicative Rational -instance DecidablyCancellableR_ Multiplicative Rational where tryCancelR_# _ = coerce $ flip baseDivNonZero -deriving via BaseInterop Rational instance PartiallyHasInverses_ Multiplicative Rational -instance DecidablyHasInverses_ Multiplicative Rational where tryInvert_# _ = coerce baseRecipNonZero +deriving via BaseInterop Rational instance PartiallyCancellableL Multiplication Rational +instance DecidablyCancellableL Multiplication Rational where tryCancelL# _ = coerce $ flip baseDivNonZero +deriving via BaseInterop Rational instance PartiallyCancellableR Multiplication Rational +instance DecidablyCancellableR Multiplication Rational where tryCancelR# _ = coerce baseDivNonZero +deriving via BaseInterop Rational instance PartiallyHasInverses Multiplication Rational +instance DecidablyHasInverses Multiplication Rational where tryInvert# _ = coerce baseRecipNonZero deriving via BaseInterop Rational instance IsDivisionRing Rational -- TODO: Switch-out base combinators for Lude's -instance (IsSemigroup_ this a) => IsSemigroup_ this (r -> a) where combine_ _ = Base.liftA2 (combine_ this) -instance (PartiallyCancellableL_ this a) => PartiallyCancellableL_ this (r -> a) where cancelL'_ _ = Base.liftA2 (cancelL'_ this) -instance (PartiallyCancellableR_ this a) => PartiallyCancellableR_ this (r -> a) where cancelR'_ _ = Base.liftA2 (cancelR'_ this) -instance (IsMonoid_ this a) => IsMonoid_ this (r -> a) where neutral_ _ = Base.const (neutral_ this) -instance (PartiallyHasInverses_ this a) => PartiallyHasInverses_ this (r -> a) where invert'_ _ = Base.fmap (invert'_ this) -instance (IsGroup_ this a) => DecidablyCancellableL_ this (r -> a) where tryCancelL_# _ = just# .* cancelL'_ this -instance (IsGroup_ this a) => DecidablyCancellableR_ this (r -> a) where tryCancelR_# _ = just# .* cancelR'_ this -instance (IsGroup_ this a) => DecidablyHasInverses_ this (r -> a) where tryInvert_# _ = just# . invert'_ this -instance (IsGroup_ this a) => IsGroup_ this (r -> a) -instance (Commutative_ this a) => Commutative_ this (r -> a) +instance (IsSemigroupWith op a) => IsSemigroupWith op (r -> a) where operation _ = Base.liftA2 (operation op) +instance (PartiallyCancellableL op a) => PartiallyCancellableL op (r -> a) where pcancelL _ = Base.liftA2 (pcancelL op) +instance (PartiallyCancellableR op a) => PartiallyCancellableR op (r -> a) where pcancelR _ = Base.liftA2 (pcancelR op) +instance (IsMonoidWith op a) => IsMonoidWith op (r -> a) where neutral _ = Base.const (neutral op) +instance (PartiallyHasInverses op a) => PartiallyHasInverses op (r -> a) where pinvert _ = Base.fmap (pinvert op) +instance (IsGroupWith op a) => DecidablyCancellableL op (r -> a) where tryCancelL# _ = just# .* cancelL op +instance (IsGroupWith op a) => DecidablyCancellableR op (r -> a) where tryCancelR# _ = just# .* cancelR op +instance (IsGroupWith op a) => DecidablyHasInverses op (r -> a) where tryInvert# _ = just# . invert op +instance (IsGroupWith op a) => IsGroupWith op (r -> a) +instance (HasCommutative op a) => HasCommutative op (r -> a) instance (IsSemiring a) => IsSemiring (r -> a) instance (IsRing a) => IsRing (r -> a)