lude

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

commit b40f468c8ea5209a59a422eb9ecb9ab26f92794f
parent e6a72b4809b29d1a2dba3d5766001ef2b3df7e41
Author: Robert Russell <robert@rr3.xyz>
Date:   Fri, 16 Oct 2026 10:14:45 -0700

Algebra.Magma: add fromInteger

Diffstat:
Msrc/Lude/Algebra/Magma.hs | 39+++++++++++++++++++++++++++++++--------
1 file changed, 31 insertions(+), 8 deletions(-)

diff --git a/src/Lude/Algebra/Magma.hs b/src/Lude/Algebra/Magma.hs @@ -173,23 +173,29 @@ module Lude.Algebra.Magma ( IsCommRing, IsDivisionRing, IsField, + fromInteger, ) where import Data.Coerce import Data.Text (Text) import Data.Text qualified as Text -import Numeric.Natural (Natural) import Numeric.Natural qualified as Base -import Prelude (Integer, Rational) +import Prelude (Rational) import Prelude qualified as Base import Lude.Algebra.Category.Core +import Lude.Error import Lude.Function import Lude.Haskell +import Lude.Integer import Lude.Maybe +import Lude.Natural -- TODO: Break this up. +-- TODO: Generally make this depend less-directly on base (i.e., re-export more +-- from Lude.Haskell) + -- TODO: We should somehow connect these to the categorical abstractions, so -- that we don't have two abstraction islands. E.g., maybe all these should be -- required to form an Eilenberg-Moore algebra (except the truely @@ -680,14 +686,23 @@ type IsCommMulGroup = Comm IsGroupWith Multiplication :: AlgebraClass -- TODO: DecidableZero for decidable division rings (and fields)? type IsSemiring :: AlgebraClass -class (IsCommAddMonoid a, IsMulMonoid a) => IsSemiring (a :: Type# r) +class (IsCommAddMonoid a, IsMulMonoid a) => IsSemiring (a :: Type# r) where + ofNatural :: Natural -> a + ofNatural = \case + NaturalZero -> zero + NaturalSucc n -> app2# (+) one (ofNatural n) type IsCommSemiring :: AlgebraClass class (IsSemiring a, MulCommutative a) => IsCommSemiring (a :: Type# r) instance (IsSemiring a, MulCommutative a) => IsCommSemiring (a :: Type# r) type IsRing :: AlgebraClass -class (IsSemiring a, IsAddGroup a) => IsRing (a :: Type# r) +class (IsSemiring a, IsAddGroup a) => IsRing (a :: Type# r) where + ofInteger :: Integer -> a + ofInteger = \case + IntegerNegSucc n -> negate $# ofNatural (NaturalSucc n) + IntegerZero -> zero + IntegerPosSucc n -> ofNatural (NaturalSucc n) type IsCommRing :: AlgebraClass class (IsRing a, MulCommutative a) => IsCommRing (a :: Type# r) @@ -700,6 +715,14 @@ type IsField :: AlgebraClass class (IsDivisionRing a, MulCommutative a) => IsField a instance (IsDivisionRing a, MulCommutative a) => IsField a +-- TODO: This probably doesn't belong here. +fromInteger :: forall {r :: Repr} (a :: Type# r). (IsSemiring a) => Integer -> a +fromInteger = \case + IntegerNegSucc _ -> panic "fromInteger on negative integer; disable NegativeLiterals" + IntegerZero -> ofNatural NaturalZero + IntegerPosSucc n -> ofNatural (NaturalSucc n) +{-# INLINE fromInteger #-} + -------------------------------------------------------------------------------- baseZero :: (Base.Num a) => a @@ -720,8 +743,8 @@ 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.Num a) => IsSemiring (BaseInterop a) where ofNatural = coerce Base.fromIntegral +instance (Base.Num a) => IsRing (BaseInterop a) where ofInteger = coerce Base.fromInteger 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 @@ -800,8 +823,8 @@ instance (IsGroupWith op a) => DecidablyCancellableR op (r -> a) where tryCancel 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) +instance (IsSemiring a) => IsSemiring (r -> a) where ofNatural = Base.const . ofNatural +instance (IsRing a) => IsRing (r -> a) where ofInteger = Base.const . ofInteger deriving via BaseInterop Text instance IsSemigroupWith Combination Text instance PartiallyCancellableL Combination Text where pcancelL _ p x = Text.stripPrefix p x ?? x