Initial commit

This commit is contained in:
La Ancapo 2026-01-25 02:27:22 +01:00
commit c101616e62
309 changed files with 53937 additions and 0 deletions

View file

@ -0,0 +1,271 @@
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DefaultSignatures #-}
{-# OPTIONS_GHC -fno-prof-auto #-}
module Basement.Numerical.Additive
( Additive(..)
) where
#include "MachDeps.h"
import Basement.Compat.Base
import Basement.Compat.C.Types
import Basement.Compat.Natural
import Basement.Compat.Primitive
import Basement.Numerical.Number
import qualified Prelude
import GHC.Types (Float(..), Double(..))
import GHC.Prim (plusWord#, plusFloat#, (+#), (+##))
import qualified GHC.Prim
import GHC.Int
import GHC.Word
import Basement.Bounded
import Basement.Nat
import Basement.Types.Word128 (Word128)
import Basement.Types.Word256 (Word256)
import qualified Basement.Types.Word128 as Word128
import qualified Basement.Types.Word256 as Word256
#if WORD_SIZE_IN_BITS < 64
import GHC.IntWord64
#endif
-- | Represent class of things that can be added together,
-- contains a neutral element and is commutative.
--
-- > x + azero = x
-- > azero + x = x
-- > x + y = y + x
--
class Additive a where
{-# MINIMAL azero, (+) #-}
azero :: a -- the identity element over addition
(+) :: a -> a -> a -- the addition
scale :: IsNatural n => n -> a -> a -- scale: repeated addition
default scale :: (Enum n, IsNatural n) => n -> a -> a
scale = scaleEnum
scaleEnum :: (Enum n, IsNatural n, Additive a) => n -> a -> a
scaleEnum 0 _ = azero
scaleEnum 1 a = a
scaleEnum 2 a = a + a
scaleEnum n a = a + scaleEnum (pred n) a -- TODO optimise. define by group of 2.
infixl 6 +
instance Additive Integer where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive Int where
azero = 0
(I# a) + (I# b) = I# (a +# b)
scale = scaleNum
instance Additive Int8 where
azero = 0
(I8# a) + (I8# b) = I8# (a `plusInt8#` b)
scale = scaleNum
instance Additive Int16 where
azero = 0
(I16# a) + (I16# b) = I16# (a `plusInt16#` b)
scale = scaleNum
instance Additive Int32 where
azero = 0
(I32# a) + (I32# b) = I32# (a `plusInt32#` b)
scale = scaleNum
instance Additive Int64 where
azero = 0
#if WORD_SIZE_IN_BITS == 64
#if __GLASGOW_HASKELL__ >= 904
(I64# a) + (I64# b) = I64# (GHC.Prim.intToInt64# (GHC.Prim.int64ToInt# a +# GHC.Prim.int64ToInt# b))
#else
(I64# a) + (I64# b) = I64# (a +# b)
#endif
#else
(I64# a) + (I64# b) = I64# (a `plusInt64#` b)
#endif
scale = scaleNum
instance Additive Word where
azero = 0
(W# a) + (W# b) = W# (a `plusWord#` b)
scale = scaleNum
instance Additive Natural where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive Word8 where
azero = 0
(W8# a) + (W8# b) = W8# (a `plusWord8#` b)
scale = scaleNum
instance Additive Word16 where
azero = 0
(W16# a) + (W16# b) = W16# (a `plusWord16#` b)
scale = scaleNum
instance Additive Word32 where
azero = 0
(W32# a) + (W32# b) = W32# (a `plusWord32#` b)
scale = scaleNum
instance Additive Word64 where
azero = 0
#if WORD_SIZE_IN_BITS == 64
#if __GLASGOW_HASKELL__ >= 904
(W64# a) + (W64# b) = W64# (GHC.Prim.wordToWord64# (GHC.Prim.word64ToWord# a `plusWord#` GHC.Prim.word64ToWord# b))
#else
(W64# a) + (W64# b) = W64# (a `plusWord#` b)
#endif
#else
(W64# a) + (W64# b) = W64# (int64ToWord64# (word64ToInt64# a `plusInt64#` word64ToInt64# b))
#endif
scale = scaleNum
instance Additive Word128 where
azero = 0
(+) = (Word128.+)
scale = scaleNum
instance Additive Word256 where
azero = 0
(+) = (Word256.+)
scale = scaleNum
instance Additive Prelude.Float where
azero = 0.0
(F# a) + (F# b) = F# (a `plusFloat#` b)
scale = scaleNum
instance Additive Prelude.Double where
azero = 0.0
(D# a) + (D# b) = D# (a +## b)
scale = scaleNum
instance Additive Prelude.Rational where
azero = 0.0
(+) = (Prelude.+)
scale = scaleNum
instance (KnownNat n, NatWithinBound Word64 n) => Additive (Zn64 n) where
azero = zn64 0
(+) = (Prelude.+)
scale = scaleNum
instance KnownNat n => Additive (Zn n) where
azero = zn 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CChar where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CSChar where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CUChar where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CShort where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CUShort where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CInt where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CUInt where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CLong where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CULong where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CPtrdiff where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CSize where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CWchar where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CSigAtomic where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CLLong where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CULLong where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CIntPtr where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CUIntPtr where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CIntMax where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CUIntMax where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CClock where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CTime where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CUSeconds where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CSUSeconds where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive COff where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CFloat where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive CDouble where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
scaleNum :: (Prelude.Num a, IsNatural n) => n -> a -> a
scaleNum n a = (Prelude.fromIntegral $ toNatural n) Prelude.* a

View file

@ -0,0 +1,135 @@
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
module Basement.Numerical.Conversion
( intToInt64
, int64ToInt
, intToWord
, wordToWord64
, word64ToWord
, Word32x2(..)
, word64ToWord32s
, wordToChar
, wordToInt
, word64ToWord#
, charToInt
, int64ToWord64
, word64ToInt64
) where
#include "MachDeps.h"
import GHC.Types
import GHC.Prim hiding (word64ToWord#)
import qualified GHC.Prim
import GHC.Int
import GHC.Word
import Basement.Compat.Primitive
#if WORD_SIZE_IN_BITS < 64
import GHC.IntWord64
#endif
intToInt64 :: Int -> Int64
#if WORD_SIZE_IN_BITS == 64
#if __GLASGOW_HASKELL__ >= 904
intToInt64 (I# i) = I64# (intToInt64# i)
#else
intToInt64 (I# i) = I64# i
#endif
#else
intToInt64 (I# i) = I64# (intToInt64# i)
#endif
int64ToInt :: Int64 -> Int
#if WORD_SIZE_IN_BITS == 64
#if __GLASGOW_HASKELL__ >= 904
int64ToInt (I64# i) = I# (int64ToInt# i)
#else
int64ToInt (I64# i) = I# i
#endif
#else
int64ToInt (I64# i) = I# (int64ToInt# i)
#endif
wordToWord64 :: Word -> Word64
#if WORD_SIZE_IN_BITS == 64
#if __GLASGOW_HASKELL__ >= 904
wordToWord64 (W# i) = W64# (wordToWord64# i)
#else
wordToWord64 (W# i) = W64# i
#endif
#else
wordToWord64 (W# i) = W64# (wordToWord64# i)
#endif
word64ToWord :: Word64 -> Word
#if WORD_SIZE_IN_BITS == 64
#if __GLASGOW_HASKELL__ >= 904
word64ToWord (W64# i) = W# (GHC.Prim.word64ToWord# i)
#else
word64ToWord (W64# i) = W# i
#endif
#else
word64ToWord (W64# i) = W# (word64ToWord# i)
#endif
word64ToInt64 :: Word64 -> Int64
#if WORD_SIZE_IN_BITS == 64
#if __GLASGOW_HASKELL__ >= 904
word64ToInt64 (W64# i) = I64# (word64ToInt64# i)
#else
word64ToInt64 (W64# i) = I64# (word2Int# i)
#endif
#else
word64ToInt64 (W64# i) = I64# (word64ToInt64# i)
#endif
int64ToWord64 :: Int64 -> Word64
#if WORD_SIZE_IN_BITS == 64
#if __GLASGOW_HASKELL__ >= 904
int64ToWord64 (I64# i) = W64# (int64ToWord64# i)
#else
int64ToWord64 (I64# i) = W64# (int2Word# i)
#endif
#else
int64ToWord64 (I64# i) = W64# (int64ToWord64# i)
#endif
#if WORD_SIZE_IN_BITS == 64
word64ToWord# :: Word# -> Word#
word64ToWord# i = i
{-# INLINE word64ToWord# #-}
#endif
-- | 2 Word32s
data Word32x2 = Word32x2 {-# UNPACK #-} !Word32
{-# UNPACK #-} !Word32
#if WORD_SIZE_IN_BITS == 64
word64ToWord32s :: Word64 -> Word32x2
#if __GLASGOW_HASKELL__ >= 904
word64ToWord32s (W64# w64) = Word32x2 (W32# (wordToWord32# (uncheckedShiftRL# (GHC.Prim.word64ToWord# w64 ) 32#))) (W32# (wordToWord32# (GHC.Prim.word64ToWord# w64)))
#else
word64ToWord32s (W64# w64) = Word32x2 (W32# (wordToWord32# (uncheckedShiftRL# w64 32#))) (W32# (wordToWord32# w64))
#endif
#else
word64ToWord32s :: Word64 -> Word32x2
word64ToWord32s (W64# w64) = Word32x2 (W32# (word64ToWord# (uncheckedShiftRL64# w64 32#))) (W32# (word64ToWord# w64))
#endif
wordToChar :: Word -> Char
wordToChar (W# word) = C# (chr# (word2Int# word))
wordToInt :: Word -> Int
wordToInt (W# word) = I# (word2Int# word)
intToWord :: Int -> Word
intToWord (I# i) = W# (int2Word# i)
charToInt :: Char -> Int
charToInt (C# x) = I# (ord# x)

View file

@ -0,0 +1,331 @@
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE DefaultSignatures #-}
module Basement.Numerical.Multiplicative
( Multiplicative(..)
, IDivisible(..)
, Divisible(..)
, recip
) where
import Basement.Compat.Base
import Basement.Compat.C.Types
import Basement.Compat.Natural
import Basement.Compat.NumLiteral
import Basement.Numerical.Number
import Basement.Numerical.Additive
import Basement.Types.Word128 (Word128)
import Basement.Types.Word256 (Word256)
import qualified Basement.Types.Word128 as Word128
import qualified Basement.Types.Word256 as Word256
import qualified Prelude
-- | Represent class of things that can be multiplied together
--
-- > x * midentity = x
-- > midentity * x = x
class Multiplicative a where
{-# MINIMAL midentity, (*) #-}
-- | Identity element over multiplication
midentity :: a
-- | Multiplication of 2 elements that result in another element
(*) :: a -> a -> a
-- | Raise to power, repeated multiplication
-- e.g.
-- > a ^ 2 = a * a
-- > a ^ 10 = (a ^ 5) * (a ^ 5) ..
--(^) :: (IsNatural n) => a -> n -> a
(^) :: (IsNatural n, Enum n, IDivisible n) => a -> n -> a
(^) = power
-- | Represent types that supports an euclidian division
--
-- > (x div y) * y + (x mod y) == x
class (Additive a, Multiplicative a) => IDivisible a where
{-# MINIMAL (div, mod) | divMod #-}
div :: a -> a -> a
div a b = fst $ divMod a b
mod :: a -> a -> a
mod a b = snd $ divMod a b
divMod :: a -> a -> (a, a)
divMod a b = (div a b, mod a b)
-- | Support for division between same types
--
-- This is likely to change to represent specific mathematic divisions
class Multiplicative a => Divisible a where
{-# MINIMAL (/) #-}
(/) :: a -> a -> a
infixl 7 *, /
infixr 8 ^
instance Multiplicative Integer where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative Int where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative Int8 where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative Int16 where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative Int32 where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative Int64 where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative Natural where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative Word where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative Word8 where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative Word16 where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative Word32 where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative Word64 where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative Word128 where
midentity = 1
(*) = (Word128.*)
instance Multiplicative Word256 where
midentity = 1
(*) = (Word256.*)
instance Multiplicative Prelude.Float where
midentity = 1.0
(*) = (Prelude.*)
instance Multiplicative Prelude.Double where
midentity = 1.0
(*) = (Prelude.*)
instance Multiplicative Prelude.Rational where
midentity = 1.0
(*) = (Prelude.*)
instance Multiplicative CChar where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CSChar where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CUChar where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CShort where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CUShort where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CInt where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CUInt where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CLong where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CULong where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CPtrdiff where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CSize where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CWchar where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CSigAtomic where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CLLong where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CULLong where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CIntPtr where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CUIntPtr where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CIntMax where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CUIntMax where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CClock where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CTime where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CUSeconds where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CSUSeconds where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative COff where
midentity = 1
(*) = (Prelude.*)
instance Multiplicative CFloat where
midentity = 1.0
(*) = (Prelude.*)
instance Multiplicative CDouble where
midentity = 1.0
(*) = (Prelude.*)
instance IDivisible Integer where
div = Prelude.div
mod = Prelude.mod
instance IDivisible Int where
div = Prelude.div
mod = Prelude.mod
instance IDivisible Int8 where
div = Prelude.div
mod = Prelude.mod
instance IDivisible Int16 where
div = Prelude.div
mod = Prelude.mod
instance IDivisible Int32 where
div = Prelude.div
mod = Prelude.mod
instance IDivisible Int64 where
div = Prelude.div
mod = Prelude.mod
instance IDivisible Natural where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible Word where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible Word8 where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible Word16 where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible Word32 where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible Word64 where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible Word128 where
div = Word128.quot
mod = Word128.rem
instance IDivisible Word256 where
div = Word256.quot
mod = Word256.rem
instance IDivisible CChar where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CSChar where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CUChar where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CShort where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CUShort where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CInt where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CUInt where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CLong where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CULong where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CPtrdiff where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CSize where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CWchar where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CSigAtomic where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CLLong where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CULLong where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CIntPtr where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CUIntPtr where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CIntMax where
div = Prelude.quot
mod = Prelude.rem
instance IDivisible CUIntMax where
div = Prelude.quot
mod = Prelude.rem
instance Divisible Prelude.Rational where
(/) = (Prelude./)
instance Divisible Float where
(/) = (Prelude./)
instance Divisible Double where
(/) = (Prelude./)
instance Divisible CFloat where
(/) = (Prelude./)
instance Divisible CDouble where
(/) = (Prelude./)
recip :: Divisible a => a -> a
recip x = midentity / x
power :: (Enum n, IsNatural n, IDivisible n, Multiplicative a) => a -> n -> a
power a n
| n == 0 = midentity
| otherwise = squaring midentity a n
where
squaring y x i
| i == 0 = y
| i == 1 = x * y
| even i = squaring y (x*x) (i`div`2)
| otherwise = squaring (x*y) (x*x) (pred i`div` 2)
even :: (IDivisible n, IsIntegral n) => n -> Bool
even n = (n `mod` 2) == 0

View file

@ -0,0 +1,128 @@
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# Language CPP #-}
module Basement.Numerical.Number
( IsIntegral(..)
, IsNatural(..)
) where
import Basement.Compat.Base
import Basement.Compat.C.Types
import Basement.Compat.Natural
import Basement.Compat.NumLiteral
import Data.Bits
import qualified Prelude
-- | Number literals, convertible through the generic Integer type.
--
-- all number are Enum'erable, meaning that you can move to
-- next element
class (Integral a, Eq a, Ord a) => IsIntegral a where
{-# MINIMAL toInteger #-}
toInteger :: a -> Integer
-- | Non Negative Number literals, convertible through the generic Natural type
class IsIntegral a => IsNatural a where
{-# MINIMAL toNatural #-}
toNatural :: a -> Natural
instance IsIntegral Integer where
toInteger i = i
instance IsIntegral Int where
toInteger i = Prelude.toInteger i
instance IsIntegral Int8 where
toInteger i = Prelude.toInteger i
instance IsIntegral Int16 where
toInteger i = Prelude.toInteger i
instance IsIntegral Int32 where
toInteger i = Prelude.toInteger i
instance IsIntegral Int64 where
toInteger i = Prelude.toInteger i
instance IsIntegral Natural where
toInteger i = Prelude.toInteger i
instance IsIntegral Word where
toInteger i = Prelude.toInteger i
instance IsIntegral Word8 where
toInteger i = Prelude.toInteger i
instance IsIntegral Word16 where
toInteger i = Prelude.toInteger i
instance IsIntegral Word32 where
toInteger i = Prelude.toInteger i
instance IsIntegral Word64 where
toInteger i = Prelude.toInteger i
instance IsIntegral CChar where
toInteger i = Prelude.toInteger i
instance IsIntegral CSChar where
toInteger i = Prelude.toInteger i
instance IsIntegral CUChar where
toInteger i = Prelude.toInteger i
instance IsIntegral CShort where
toInteger i = Prelude.toInteger i
instance IsIntegral CUShort where
toInteger i = Prelude.toInteger i
instance IsIntegral CInt where
toInteger i = Prelude.toInteger i
instance IsIntegral CUInt where
toInteger i = Prelude.toInteger i
instance IsIntegral CLong where
toInteger i = Prelude.toInteger i
instance IsIntegral CULong where
toInteger i = Prelude.toInteger i
instance IsIntegral CPtrdiff where
toInteger i = Prelude.toInteger i
instance IsIntegral CSize where
toInteger i = Prelude.toInteger i
instance IsIntegral CWchar where
toInteger i = Prelude.toInteger i
instance IsIntegral CSigAtomic where
toInteger i = Prelude.toInteger i
instance IsIntegral CLLong where
toInteger i = Prelude.toInteger i
instance IsIntegral CULLong where
toInteger i = Prelude.toInteger i
#if MIN_VERSION_base(4,10,0)
instance IsIntegral CBool where
toInteger i = Prelude.toInteger i
#endif
instance IsIntegral CIntPtr where
toInteger i = Prelude.toInteger i
instance IsIntegral CUIntPtr where
toInteger i = Prelude.toInteger i
instance IsIntegral CIntMax where
toInteger i = Prelude.toInteger i
instance IsIntegral CUIntMax where
toInteger i = Prelude.toInteger i
instance IsNatural Natural where
toNatural i = i
instance IsNatural Word where
toNatural i = Prelude.fromIntegral i
instance IsNatural Word8 where
toNatural i = Prelude.fromIntegral i
instance IsNatural Word16 where
toNatural i = Prelude.fromIntegral i
instance IsNatural Word32 where
toNatural i = Prelude.fromIntegral i
instance IsNatural Word64 where
toNatural i = Prelude.fromIntegral i
instance IsNatural CUChar where
toNatural i = Prelude.fromIntegral i
instance IsNatural CUShort where
toNatural i = Prelude.fromIntegral i
instance IsNatural CUInt where
toNatural i = Prelude.fromIntegral i
instance IsNatural CULong where
toNatural i = Prelude.fromIntegral i
instance IsNatural CSize where
toNatural i = Prelude.fromIntegral i
instance IsNatural CULLong where
toNatural i = Prelude.fromIntegral i
instance IsNatural CUIntPtr where
toNatural i = Prelude.fromIntegral i
instance IsNatural CUIntMax where
toNatural i = Prelude.fromIntegral i

View file

@ -0,0 +1,186 @@
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE CPP, UndecidableInstances, TypeFamilies #-}
module Basement.Numerical.Subtractive
( Subtractive(..)
) where
import Basement.Compat.Base
import Basement.Compat.C.Types
import Basement.Compat.Natural
import Basement.IntegralConv
import Basement.Bounded
import Basement.Nat
import Basement.Types.Word128 (Word128)
import Basement.Types.Word256 (Word256)
import qualified Basement.Types.Word128 as Word128
import qualified Basement.Types.Word256 as Word256
import qualified Prelude
-- | Represent class of things that can be subtracted.
--
--
-- Note that the result is not necessary of the same type
-- as the operand depending on the actual type.
--
-- For example:
--
-- > (-) :: Int -> Int -> Int
-- > (-) :: DateTime -> DateTime -> Seconds
-- > (-) :: Ptr a -> Ptr a -> PtrDiff
-- > (-) :: Natural -> Natural -> Maybe Natural
class Subtractive a where
type Difference a
(-) :: a -> a -> Difference a
infixl 6 -
instance Subtractive Integer where
type Difference Integer = Integer
(-) = (Prelude.-)
instance Subtractive Int where
type Difference Int = Int
(-) = (Prelude.-)
instance Subtractive Int8 where
type Difference Int8 = Int8
(-) = (Prelude.-)
instance Subtractive Int16 where
type Difference Int16 = Int16
(-) = (Prelude.-)
instance Subtractive Int32 where
type Difference Int32 = Int32
(-) = (Prelude.-)
instance Subtractive Int64 where
type Difference Int64 = Int64
(-) = (Prelude.-)
instance Subtractive Natural where
type Difference Natural = Maybe Natural
(-) a b
| b > a = Nothing
| otherwise = Just (a Prelude.- b)
instance Subtractive Word where
type Difference Word = Word
(-) = (Prelude.-)
instance Subtractive Word8 where
type Difference Word8 = Word8
(-) = (Prelude.-)
instance Subtractive Word16 where
type Difference Word16 = Word16
(-) = (Prelude.-)
instance Subtractive Word32 where
type Difference Word32 = Word32
(-) = (Prelude.-)
instance Subtractive Word64 where
type Difference Word64 = Word64
(-) = (Prelude.-)
instance Subtractive Word128 where
type Difference Word128 = Word128
(-) = (Word128.-)
instance Subtractive Word256 where
type Difference Word256 = Word256
(-) = (Word256.-)
instance Subtractive Prelude.Float where
type Difference Prelude.Float = Prelude.Float
(-) = (Prelude.-)
instance Subtractive Prelude.Double where
type Difference Prelude.Double = Prelude.Double
(-) = (Prelude.-)
instance Subtractive Prelude.Char where
type Difference Prelude.Char = Prelude.Int
(-) a b = (Prelude.-) (charToInt a) (charToInt b)
instance (KnownNat n, NatWithinBound Word64 n) => Subtractive (Zn64 n) where
type Difference (Zn64 n) = Zn64 n
(-) a b = (Prelude.-) a b
instance KnownNat n => Subtractive (Zn n) where
type Difference (Zn n) = Zn n
(-) a b = (Prelude.-) a b
instance Subtractive CChar where
type Difference CChar = CChar
(-) = (Prelude.-)
instance Subtractive CSChar where
type Difference CSChar = CSChar
(-) = (Prelude.-)
instance Subtractive CUChar where
type Difference CUChar = CUChar
(-) = (Prelude.-)
instance Subtractive CShort where
type Difference CShort = CShort
(-) = (Prelude.-)
instance Subtractive CUShort where
type Difference CUShort = CUShort
(-) = (Prelude.-)
instance Subtractive CInt where
type Difference CInt = CInt
(-) = (Prelude.-)
instance Subtractive CUInt where
type Difference CUInt = CUInt
(-) = (Prelude.-)
instance Subtractive CLong where
type Difference CLong = CLong
(-) = (Prelude.-)
instance Subtractive CULong where
type Difference CULong = CULong
(-) = (Prelude.-)
instance Subtractive CPtrdiff where
type Difference CPtrdiff = CPtrdiff
(-) = (Prelude.-)
instance Subtractive CSize where
type Difference CSize = CSize
(-) = (Prelude.-)
instance Subtractive CWchar where
type Difference CWchar = CWchar
(-) = (Prelude.-)
instance Subtractive CSigAtomic where
type Difference CSigAtomic = CSigAtomic
(-) = (Prelude.-)
instance Subtractive CLLong where
type Difference CLLong = CLLong
(-) = (Prelude.-)
instance Subtractive CULLong where
type Difference CULLong = CULLong
(-) = (Prelude.-)
#if MIN_VERSION_base(4,10,0)
instance Subtractive CBool where
type Difference CBool = CBool
(-) = (Prelude.-)
#endif
instance Subtractive CIntPtr where
type Difference CIntPtr = CIntPtr
(-) = (Prelude.-)
instance Subtractive CUIntPtr where
type Difference CUIntPtr = CUIntPtr
(-) = (Prelude.-)
instance Subtractive CIntMax where
type Difference CIntMax = CIntMax
(-) = (Prelude.-)
instance Subtractive CUIntMax where
type Difference CUIntMax = CUIntMax
(-) = (Prelude.-)
instance Subtractive CClock where
type Difference CClock = CClock
(-) = (Prelude.-)
instance Subtractive CTime where
type Difference CTime = CTime
(-) = (Prelude.-)
instance Subtractive CUSeconds where
type Difference CUSeconds = CUSeconds
(-) = (Prelude.-)
instance Subtractive CSUSeconds where
type Difference CSUSeconds = CSUSeconds
(-) = (Prelude.-)
instance Subtractive COff where
type Difference COff = COff
(-) = (Prelude.-)
instance Subtractive CFloat where
type Difference CFloat = CFloat
(-) = (Prelude.-)
instance Subtractive CDouble where
type Difference CDouble = CDouble
(-) = (Prelude.-)