{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoStarIsType #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RoleAnnotations #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}
module Data.SNumber
(
SNumber(SNumber, N#, SN, unSNumber), SNumberRepr(..)
, snumber, trySNumber
, unsafeUncheckedSNumber
, unsafeMkSNumber, unsafeTryMkSNumber, unsafeUncheckedMkSNumber
, SomeSNumber(..), someSNumberVal, withSNumber
, compareSNumber, sameSNumber
, OverflowArith(..)
, tryAdd, trySub, tryMul
, UnrepresentableSNumber(..)
, chkAdd, chkSub, chkMul
, divExact
, KnownSNumber(..), snumberVal
, reifySNumber, reifySNumberAsNat
, IntBits, IntMin, IntMaxP1
, WordBits, WordMaxP1
) where
import Control.Exception (Exception, throw)
import Data.Kind (Constraint, Type)
import Data.Maybe (fromMaybe)
import Data.Proxy (Proxy(..))
import Data.Type.Equality ((:~:)(Refl))
import GHC.Exts
( Word(W#), addWordC#, subWordC#, timesWord2#
, Int(I#), addIntC#, subIntC#, mulIntMayOflo#, (*#)
)
import GHC.Stack (HasCallStack, withFrozenCallStack)
import GHC.TypeNats (type (^), KnownNat, Nat, SomeNat(..), someNatVal)
import Numeric.Natural (Natural)
import Unsafe.Coerce (unsafeCoerce)
import Data.SNumber.Internal
( NegativeReprUnsignedErr, OutOfReprRangeErr
, IsAtLeastMinBound, IsLessThanMaxBound, ForbidNegZero
)
import Kinds.Integer (CmpInteger, KnownInteger(..), pattern Pos, pattern Neg)
import qualified Kinds.Integer as K (Integer)
import Kinds.Ord (OrderingI(..))
import Kinds.Num (type (+), type (-), type (*))
#include "MachDeps.h"
newtype SNumber a (n :: K.Integer) = MkSNumber# a
deriving newtype Int -> SNumber a n -> ShowS
[SNumber a n] -> ShowS
SNumber a n -> String
(Int -> SNumber a n -> ShowS)
-> (SNumber a n -> String)
-> ([SNumber a n] -> ShowS)
-> Show (SNumber a n)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a (n :: Integer). Show a => Int -> SNumber a n -> ShowS
forall a (n :: Integer). Show a => [SNumber a n] -> ShowS
forall a (n :: Integer). Show a => SNumber a n -> String
showList :: [SNumber a n] -> ShowS
$cshowList :: forall a (n :: Integer). Show a => [SNumber a n] -> ShowS
show :: SNumber a n -> String
$cshow :: forall a (n :: Integer). Show a => SNumber a n -> String
showsPrec :: Int -> SNumber a n -> ShowS
$cshowsPrec :: forall a (n :: Integer). Show a => Int -> SNumber a n -> ShowS
Show
type role SNumber nominal nominal
pattern N# :: forall (n :: K.Integer) a. a -> SNumber a n
pattern $bN# :: a -> SNumber a n
$mN# :: forall r (n :: Integer) a.
SNumber a n -> (a -> r) -> (Void# -> r) -> r
N# x = MkSNumber# x
{-# COMPLETE N# #-}
pattern SN :: forall (n :: K.Integer) a. a -> SNumber a n
pattern $mSN :: forall r (n :: Integer) a.
SNumber a n -> (a -> r) -> (Void# -> r) -> r
SN {SNumber a n -> a
unSNumber} <- MkSNumber# unSNumber
{-# COMPLETE SN #-}
data KnownSNumberDict a n = KnownSNumber a n => KnownSNumberDict
pattern SNumber
:: forall (n :: K.Integer) a. SNumberRepr a => KnownSNumber a n => SNumber a n
pattern $bSNumber :: SNumber a n
$mSNumber :: forall r (n :: Integer) a.
SNumberRepr a =>
SNumber a n -> (KnownSNumber a n => r) -> (Void# -> r) -> r
SNumber <-
((\x -> reifySNumber x (KnownSNumberDict @a @n)) -> KnownSNumberDict)
where
SNumber = SNumber a n
forall (n :: Integer) a. KnownSNumber a n => SNumber a n
snumberVal
{-# COMPLETE SNumber #-}
class LitIsAnything (n :: K.Integer)
instance ForbidNegZero n => LitIsAnything n
class LitIsUnsignedBits
(w :: Nat)
repr
(a :: K.Integer -> Type)
(n :: K.Integer)
instance ( IsAtLeastMinBound ('Pos 0) (NegativeReprUnsignedErr repr a) n
, IsLessThanMaxBound
('Pos (2 ^ w))
(OutOfReprRangeErr ('Pos 0) ('Pos (2 ^ w)) repr a)
n
, ForbidNegZero n
)
=> LitIsUnsignedBits w repr a n
type SignedReprRangeErr w =
OutOfReprRangeErr ('Neg (2 ^ (w - 1))) ('Pos (2 ^ (w - 1)))
class LitIsSignedBits (w :: Nat) repr (a :: K.Integer -> Type) (n :: K.Integer)
instance ( IsAtLeastMinBound
('Neg (2 ^ (w - 1)))
(SignedReprRangeErr w repr a)
n
, IsLessThanMaxBound
('Pos (2 ^ (w - 1)))
(SignedReprRangeErr w repr a)
n
, ForbidNegZero n
)
=> LitIsSignedBits w repr a n
type LitIsNonNegative repr a =
IsAtLeastMinBound ('Pos 0) (NegativeReprUnsignedErr repr a)
type WordBits = WORD_SIZE_IN_BITS
type WordMaxP1 = 'Pos (2 ^ WordBits)
type IntBits = WORD_SIZE_IN_BITS
type IntMin = 'Neg (2 ^ (IntBits - 1))
type IntMaxP1 = 'Pos (2 ^ (IntBits - 1))
class Integral a => SNumberRepr a where
type SafeSNumber a :: K.Integer -> Constraint
instance SNumberRepr Int where
type SafeSNumber Int = LitIsSignedBits IntBits Int (SNumber Int)
instance SNumberRepr Word where
type SafeSNumber Word = LitIsUnsignedBits WordBits Word (SNumber Word)
instance SNumberRepr Integer where
type SafeSNumber Integer = LitIsAnything
instance SNumberRepr Natural where
type SafeSNumber Natural = LitIsNonNegative Natural (SNumber Natural)
snumber
:: forall n a
. (SNumberRepr a, SafeSNumber a n, KnownInteger n)
=> SNumber a n
snumber :: SNumber a n
snumber = a -> SNumber a n
forall (n :: Integer) a. SafeSNumber a n => a -> SNumber a n
unsafeMkSNumber (Integer -> a
forall a. Num a => Integer -> a
fromInteger (KnownInteger n => Integer
forall (n :: Integer). KnownInteger n => Integer
integerVal @n))
trySNumber
:: forall n a
. (SNumberRepr a, KnownInteger n)
=> Maybe (SNumber a n)
trySNumber :: Maybe (SNumber a n)
trySNumber = Integer -> Maybe (SNumber a n)
forall (n :: Integer) a.
SNumberRepr a =>
Integer -> Maybe (SNumber a n)
unsafeTryMkSNumber (KnownInteger n => Integer
forall (n :: Integer). KnownInteger n => Integer
integerVal @n)
unsafeUncheckedSNumber :: forall n a. (Num a, KnownInteger n) => SNumber a n
unsafeUncheckedSNumber :: SNumber a n
unsafeUncheckedSNumber = a -> SNumber a n
forall (n :: Integer) a. a -> SNumber a n
unsafeUncheckedMkSNumber (Integer -> a
forall a. Num a => Integer -> a
fromInteger (KnownInteger n => Integer
forall (n :: Integer). KnownInteger n => Integer
integerVal @n))
unsafeMkSNumber :: forall n a. SafeSNumber a n => a -> SNumber a n
unsafeMkSNumber :: a -> SNumber a n
unsafeMkSNumber = a -> SNumber a n
forall (n :: Integer) a. a -> SNumber a n
N#
unsafeTryMkSNumber
:: forall n a. SNumberRepr a => Integer -> Maybe (SNumber a n)
unsafeTryMkSNumber :: Integer -> Maybe (SNumber a n)
unsafeTryMkSNumber Integer
x =
let x' :: a
x' = Integer -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
x
in if a -> Integer
forall a. Integral a => a -> Integer
toInteger a
x' Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
x then Maybe (SNumber a n)
forall a. Maybe a
Nothing else SNumber a n -> Maybe (SNumber a n)
forall a. a -> Maybe a
Just (a -> SNumber a n
forall (n :: Integer) a. a -> SNumber a n
N# a
x')
{-# INLINE unsafeTryMkSNumber #-}
unsafeUncheckedMkSNumber :: forall n a. a -> SNumber a n
unsafeUncheckedMkSNumber :: a -> SNumber a n
unsafeUncheckedMkSNumber = a -> SNumber a n
forall (n :: Integer) a. a -> SNumber a n
N#
class KnownSNumber a n where
snumberVal_ :: SNumber a n
default snumberVal_ :: (SNumberRepr a, KnownInteger n) => SNumber a n
snumberVal_ = SNumber a n -> Maybe (SNumber a n) -> SNumber a n
forall a. a -> Maybe a -> a
fromMaybe (String -> SNumber a n
forall a. HasCallStack => String -> a
error String
"KnownSNumber: unrepresentable") Maybe (SNumber a n)
forall (n :: Integer) a.
(SNumberRepr a, KnownInteger n) =>
Maybe (SNumber a n)
trySNumber
instance (SNumberRepr a, KnownInteger n) => KnownSNumber a n
snumberVal :: forall n a. KnownSNumber a n => SNumber a n
snumberVal :: SNumber a n
snumberVal = SNumber a n
forall a (n :: Integer). KnownSNumber a n => SNumber a n
snumberVal_
compareSNumber
:: forall m n a. Ord a => SNumber a m -> SNumber a n -> OrderingI m n
compareSNumber :: SNumber a m -> SNumber a n -> OrderingI m n
compareSNumber (N# a
x) (N# a
y) = case a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
x a
y of
Ordering
LT -> case (Any :~: Any) -> CmpInteger m n :~: 'LT
forall a b. a -> b
unsafeCoerce Any :~: Any
forall k (a :: k). a :~: a
Refl :: CmpInteger m n :~: 'LT of CmpInteger m n :~: 'LT
Refl -> OrderingI m n
forall k (m :: k) (n :: k). (Compare m n ~ 'LT) => OrderingI m n
LTI
Ordering
EQ ->
case (Any :~: Any) -> CmpInteger m n :~: 'EQ
forall a b. a -> b
unsafeCoerce Any :~: Any
forall k (a :: k). a :~: a
Refl :: CmpInteger m n :~: 'EQ of
CmpInteger m n :~: 'EQ
Refl -> case (Any :~: Any) -> m :~: n
forall a b. a -> b
unsafeCoerce Any :~: Any
forall k (a :: k). a :~: a
Refl :: m :~: n of
m :~: n
Refl -> OrderingI m n
forall k (m :: k). (Compare m m ~ 'EQ) => OrderingI m m
EQI
Ordering
GT -> case (Any :~: Any) -> CmpInteger m n :~: 'GT
forall a b. a -> b
unsafeCoerce Any :~: Any
forall k (a :: k). a :~: a
Refl :: CmpInteger m n :~: 'GT of CmpInteger m n :~: 'GT
Refl -> OrderingI m n
forall k (m :: k) (n :: k). (Compare m n ~ 'GT) => OrderingI m n
GTI
sameSNumber :: Eq a => SNumber a m -> SNumber a n -> Maybe (m :~: n)
sameSNumber :: SNumber a m -> SNumber a n -> Maybe (m :~: n)
sameSNumber (N# a
x) (N# a
y)
| a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
y = (m :~: n) -> Maybe (m :~: n)
forall a. a -> Maybe a
Just ((Any :~: Any) -> m :~: n
forall a b. a -> b
unsafeCoerce Any :~: Any
forall k (a :: k). a :~: a
Refl)
| Bool
otherwise = Maybe (m :~: n)
forall a. Maybe a
Nothing
newtype c :=> a = CArr (c => a)
reifySNumber :: forall a n r. SNumber a n -> (KnownSNumber a n => r) -> r
reifySNumber :: SNumber a n -> (KnownSNumber a n => r) -> r
reifySNumber SNumber a n
n KnownSNumber a n => r
r = SNumber a n -> r
f SNumber a n
n
where
f :: SNumber a n -> r
f :: SNumber a n -> r
f = (KnownSNumber a n :=> r) -> SNumber a n -> r
forall a b. a -> b
unsafeCoerce ((KnownSNumber a n => r) -> KnownSNumber a n :=> r
forall (c :: Constraint) a. (c => a) -> c :=> a
CArr KnownSNumber a n => r
r :: KnownSNumber a n :=> r)
reifySNumberAsNat
:: forall n r a
. Integral a
=> SNumber a ('Pos n) -> (KnownNat n => r) -> r
reifySNumberAsNat :: SNumber a ('Pos n) -> (KnownNat n => r) -> r
reifySNumberAsNat (N# a
x) KnownNat n => r
r = case Natural -> SomeNat
someNatVal (a -> Natural
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
x) of
SomeNat (Proxy n
_ :: Proxy m) -> case (Any :~: Any) -> n :~: n
forall a b. a -> b
unsafeCoerce Any :~: Any
forall k (a :: k). a :~: a
Refl :: n :~: m of n :~: n
Refl -> r
KnownNat n => r
r
data SomeSNumber a = forall n. SomeSNumber (SNumber a n)
someSNumberVal :: SNumberRepr a => a -> SomeSNumber a
someSNumberVal :: a -> SomeSNumber a
someSNumberVal a
x = a
-> (forall (n :: Integer). SNumber a n -> SomeSNumber a)
-> SomeSNumber a
forall a r.
SNumberRepr a =>
a -> (forall (n :: Integer). SNumber a n -> r) -> r
withSNumber a
x forall a (n :: Integer). SNumber a n -> SomeSNumber a
forall (n :: Integer). SNumber a n -> SomeSNumber a
SomeSNumber
withSNumber :: SNumberRepr a => a -> (forall n. SNumber a n -> r) -> r
withSNumber :: a -> (forall (n :: Integer). SNumber a n -> r) -> r
withSNumber a
x forall (n :: Integer). SNumber a n -> r
r = SNumber a Any -> r
forall (n :: Integer). SNumber a n -> r
r (a -> SNumber a Any
forall (n :: Integer) a. a -> SNumber a n
N# a
x)
class Integral a => OverflowArith a where
overflowAdd :: a -> a -> (Bool, a)
overflowSub :: a -> a -> (Bool, a)
overflowMul :: a -> a -> (Bool, a)
instance OverflowArith Word where
overflowAdd :: Word -> Word -> (Bool, Word)
overflowAdd (W# Word#
x) (W# Word#
y) =
case Word# -> Word# -> (# Word#, Int# #)
addWordC# Word#
x Word#
y of (# Word#
xy, Int#
ovf #) -> (Int# -> Int
I# Int#
ovf Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0, Word# -> Word
W# Word#
xy)
overflowSub :: Word -> Word -> (Bool, Word)
overflowSub (W# Word#
x) (W# Word#
y) =
case Word# -> Word# -> (# Word#, Int# #)
subWordC# Word#
x Word#
y of (# Word#
xy, Int#
ovf #) -> (Int# -> Int
I# Int#
ovf Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0, Word# -> Word
W# Word#
xy)
overflowMul :: Word -> Word -> (Bool, Word)
overflowMul (W# Word#
x) (W# Word#
y) =
case Word# -> Word# -> (# Word#, Word# #)
timesWord2# Word#
x Word#
y of (# Word#
hi, Word#
lo #) -> (Word# -> Word
W# Word#
hi Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
/= Word
0, Word# -> Word
W# Word#
lo)
instance OverflowArith Int where
overflowAdd :: Int -> Int -> (Bool, Int)
overflowAdd (I# Int#
x) (I# Int#
y) =
case Int# -> Int# -> (# Int#, Int# #)
addIntC# Int#
x Int#
y of (# Int#
xy, Int#
ovf #) -> (Int# -> Int
I# Int#
ovf Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0, Int# -> Int
I# Int#
xy)
overflowSub :: Int -> Int -> (Bool, Int)
overflowSub (I# Int#
x) (I# Int#
y) =
case Int# -> Int# -> (# Int#, Int# #)
subIntC# Int#
x Int#
y of (# Int#
xy, Int#
ovf #) -> (Int# -> Int
I# Int#
ovf Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0, Int# -> Int
I# Int#
xy)
overflowMul :: Int -> Int -> (Bool, Int)
overflowMul (I# Int#
x) (I# Int#
y) =
let xy :: Int
xy = Int# -> Int
I# (Int#
x Int# -> Int# -> Int#
*# Int#
y)
in case Int# -> Int# -> Int#
mulIntMayOflo# Int#
x Int#
y of
Int#
ovf -> if Int# -> Int
I# Int#
ovf Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0
then (Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
xy Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int# -> Int
I# Int#
x) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int# -> Int
I# Int#
y), Int
xy)
else (Bool
False, Int# -> Int
I# (Int#
x Int# -> Int# -> Int#
*# Int#
y))
instance OverflowArith Natural where
overflowAdd :: Natural -> Natural -> (Bool, Natural)
overflowAdd Natural
x Natural
y = (Bool
False, Natural
x Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
+ Natural
y)
overflowSub :: Natural -> Natural -> (Bool, Natural)
overflowSub Natural
x Natural
y = (Natural
x Natural -> Natural -> Bool
forall a. Ord a => a -> a -> Bool
> Natural
y, Natural
x Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
- Natural
y)
overflowMul :: Natural -> Natural -> (Bool, Natural)
overflowMul Natural
x Natural
y = (Bool
False, Natural
x Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
* Natural
y)
instance OverflowArith Integer where
overflowAdd :: Integer -> Integer -> (Bool, Integer)
overflowAdd Integer
x Integer
y = (Bool
False, Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
y)
overflowSub :: Integer -> Integer -> (Bool, Integer)
overflowSub Integer
x Integer
y = (Bool
False, Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
y)
overflowMul :: Integer -> Integer -> (Bool, Integer)
overflowMul Integer
x Integer
y = (Bool
False, Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
y)
unsafeMkTry
:: (a -> a -> (Bool, a)) -> SNumber a n -> SNumber a m -> Maybe (SNumber a o)
unsafeMkTry :: (a -> a -> (Bool, a))
-> SNumber a n -> SNumber a m -> Maybe (SNumber a o)
unsafeMkTry a -> a -> (Bool, a)
f (N# a
x) (N# a
y) = case a -> a -> (Bool, a)
f a
x a
y of
(Bool
True, a
_) -> Maybe (SNumber a o)
forall a. Maybe a
Nothing
(Bool
False, a
xy) -> SNumber a o -> Maybe (SNumber a o)
forall a. a -> Maybe a
Just (a -> SNumber a o
forall (n :: Integer) a. a -> SNumber a n
N# a
xy)
tryAdd
:: (SNumberRepr a, OverflowArith a)
=> SNumber a m -> SNumber a n -> Maybe (SNumber a (m + n))
tryAdd :: SNumber a m -> SNumber a n -> Maybe (SNumber a (m + n))
tryAdd = (a -> a -> (Bool, a))
-> SNumber a m -> SNumber a n -> Maybe (SNumber a (AddInteger m n))
forall a (n :: Integer) (m :: Integer) (o :: Integer).
(a -> a -> (Bool, a))
-> SNumber a n -> SNumber a m -> Maybe (SNumber a o)
unsafeMkTry a -> a -> (Bool, a)
forall a. OverflowArith a => a -> a -> (Bool, a)
overflowAdd
trySub
:: (SNumberRepr a, OverflowArith a)
=> SNumber a m -> SNumber a n -> Maybe (SNumber a (m - n))
trySub :: SNumber a m -> SNumber a n -> Maybe (SNumber a (m - n))
trySub = (a -> a -> (Bool, a))
-> SNumber a m -> SNumber a n -> Maybe (SNumber a (SubInteger m n))
forall a (n :: Integer) (m :: Integer) (o :: Integer).
(a -> a -> (Bool, a))
-> SNumber a n -> SNumber a m -> Maybe (SNumber a o)
unsafeMkTry a -> a -> (Bool, a)
forall a. OverflowArith a => a -> a -> (Bool, a)
overflowSub
tryMul
:: (SNumberRepr a, OverflowArith a)
=> SNumber a m -> SNumber a n -> Maybe (SNumber a (m * n))
tryMul :: SNumber a m -> SNumber a n -> Maybe (SNumber a (m * n))
tryMul = (a -> a -> (Bool, a))
-> SNumber a m -> SNumber a n -> Maybe (SNumber a (MulInteger m n))
forall a (n :: Integer) (m :: Integer) (o :: Integer).
(a -> a -> (Bool, a))
-> SNumber a n -> SNumber a m -> Maybe (SNumber a o)
unsafeMkTry a -> a -> (Bool, a)
forall a. OverflowArith a => a -> a -> (Bool, a)
overflowMul
data UnrepresentableSNumber = UnrepresentableSNumber String Integer Integer
deriving Int -> UnrepresentableSNumber -> ShowS
[UnrepresentableSNumber] -> ShowS
UnrepresentableSNumber -> String
(Int -> UnrepresentableSNumber -> ShowS)
-> (UnrepresentableSNumber -> String)
-> ([UnrepresentableSNumber] -> ShowS)
-> Show UnrepresentableSNumber
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UnrepresentableSNumber] -> ShowS
$cshowList :: [UnrepresentableSNumber] -> ShowS
show :: UnrepresentableSNumber -> String
$cshow :: UnrepresentableSNumber -> String
showsPrec :: Int -> UnrepresentableSNumber -> ShowS
$cshowsPrec :: Int -> UnrepresentableSNumber -> ShowS
Show
instance Exception UnrepresentableSNumber
unsafeMkChk
:: (HasCallStack, Integral a)
=> String
-> (a -> a -> (Bool, a)) -> SNumber a n -> SNumber a m -> SNumber a o
unsafeMkChk :: String
-> (a -> a -> (Bool, a))
-> SNumber a n
-> SNumber a m
-> SNumber a o
unsafeMkChk String
s a -> a -> (Bool, a)
f (N# a
x) (N# a
y) = case a -> a -> (Bool, a)
f a
x a
y of
(Bool
True, a
_) -> UnrepresentableSNumber -> SNumber a o
forall a e. Exception e => e -> a
throw (String -> Integer -> Integer -> UnrepresentableSNumber
UnrepresentableSNumber String
s (a -> Integer
forall a. Integral a => a -> Integer
toInteger a
x) (a -> Integer
forall a. Integral a => a -> Integer
toInteger a
y))
(Bool
False, a
xy) -> a -> SNumber a o
forall (n :: Integer) a. a -> SNumber a n
N# a
xy
chkAdd
:: (SNumberRepr a, OverflowArith a, HasCallStack)
=> SNumber a m -> SNumber a n -> SNumber a (m + n)
chkAdd :: SNumber a m -> SNumber a n -> SNumber a (m + n)
chkAdd = (HasCallStack =>
String
-> (a -> a -> (Bool, a))
-> SNumber a m
-> SNumber a n
-> SNumber a (AddInteger m n))
-> String
-> (a -> a -> (Bool, a))
-> SNumber a m
-> SNumber a n
-> SNumber a (AddInteger m n)
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack HasCallStack =>
String
-> (a -> a -> (Bool, a))
-> SNumber a m
-> SNumber a n
-> SNumber a (AddInteger m n)
forall a (n :: Integer) (m :: Integer) (o :: Integer).
(HasCallStack, Integral a) =>
String
-> (a -> a -> (Bool, a))
-> SNumber a n
-> SNumber a m
-> SNumber a o
unsafeMkChk String
"+" a -> a -> (Bool, a)
forall a. OverflowArith a => a -> a -> (Bool, a)
overflowAdd
chkSub
:: (SNumberRepr a, OverflowArith a, HasCallStack)
=> SNumber a m -> SNumber a n -> SNumber a (m - n)
chkSub :: SNumber a m -> SNumber a n -> SNumber a (m - n)
chkSub = (HasCallStack =>
String
-> (a -> a -> (Bool, a))
-> SNumber a m
-> SNumber a n
-> SNumber a (SubInteger m n))
-> String
-> (a -> a -> (Bool, a))
-> SNumber a m
-> SNumber a n
-> SNumber a (SubInteger m n)
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack HasCallStack =>
String
-> (a -> a -> (Bool, a))
-> SNumber a m
-> SNumber a n
-> SNumber a (SubInteger m n)
forall a (n :: Integer) (m :: Integer) (o :: Integer).
(HasCallStack, Integral a) =>
String
-> (a -> a -> (Bool, a))
-> SNumber a n
-> SNumber a m
-> SNumber a o
unsafeMkChk String
"-" a -> a -> (Bool, a)
forall a. OverflowArith a => a -> a -> (Bool, a)
overflowSub
chkMul
:: (SNumberRepr a, OverflowArith a, HasCallStack)
=> SNumber a m -> SNumber a n -> SNumber a (m * n)
chkMul :: SNumber a m -> SNumber a n -> SNumber a (m * n)
chkMul = (HasCallStack =>
String
-> (a -> a -> (Bool, a))
-> SNumber a m
-> SNumber a n
-> SNumber a (MulInteger m n))
-> String
-> (a -> a -> (Bool, a))
-> SNumber a m
-> SNumber a n
-> SNumber a (MulInteger m n)
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack HasCallStack =>
String
-> (a -> a -> (Bool, a))
-> SNumber a m
-> SNumber a n
-> SNumber a (MulInteger m n)
forall a (n :: Integer) (m :: Integer) (o :: Integer).
(HasCallStack, Integral a) =>
String
-> (a -> a -> (Bool, a))
-> SNumber a n
-> SNumber a m
-> SNumber a o
unsafeMkChk String
"*" a -> a -> (Bool, a)
forall a. OverflowArith a => a -> a -> (Bool, a)
overflowMul
divExact :: SNumberRepr a => SNumber a (m * n) -> SNumber a n -> SNumber a m
divExact :: SNumber a (m * n) -> SNumber a n -> SNumber a m
divExact = String
-> (a -> a -> (Bool, a))
-> SNumber a (MulInteger m n)
-> SNumber a n
-> SNumber a m
forall a (n :: Integer) (m :: Integer) (o :: Integer).
(HasCallStack, Integral a) =>
String
-> (a -> a -> (Bool, a))
-> SNumber a n
-> SNumber a m
-> SNumber a o
unsafeMkChk String
"/" (\a
x a
y -> (Bool
False, a
x a -> a -> a
forall a. Integral a => a -> a -> a
`div` a
y))