{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wall #-}
module NumHask.Data.Integral
( Integral (..),
ToIntegral (..),
FromIntegral (..),
FromInteger (..),
even,
odd,
(^^),
(^),
)
where
import Data.Int (Int16, Int32, Int64, Int8)
import Data.Ord
import Data.Word (Word, Word16, Word32, Word64, Word8)
import GHC.Natural (Natural (..), naturalFromInteger)
import NumHask.Algebra.Additive
import NumHask.Algebra.Multiplicative
import NumHask.Algebra.Ring
import Prelude (Double, Float, Int, Integer, fst, snd, (.))
import qualified Prelude as P
class
(Distributive a) =>
Integral a
where
infixl 7 `div`, `mod`
div :: a -> a -> a
div a
a1 a
a2 = forall a b. (a, b) -> a
fst (forall a. Integral a => a -> a -> (a, a)
divMod a
a1 a
a2)
mod :: a -> a -> a
mod a
a1 a
a2 = forall a b. (a, b) -> b
snd (forall a. Integral a => a -> a -> (a, a)
divMod a
a1 a
a2)
divMod :: a -> a -> (a, a)
quot :: a -> a -> a
quot a
a1 a
a2 = forall a b. (a, b) -> a
fst (forall a. Integral a => a -> a -> (a, a)
quotRem a
a1 a
a2)
rem :: a -> a -> a
rem a
a1 a
a2 = forall a b. (a, b) -> b
snd (forall a. Integral a => a -> a -> (a, a)
quotRem a
a1 a
a2)
quotRem :: a -> a -> (a, a)
instance Integral Int where
divMod :: Int -> Int -> (Int, Int)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
quotRem :: Int -> Int -> (Int, Int)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem
instance Integral Integer where
divMod :: Integer -> Integer -> (Integer, Integer)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
quotRem :: Integer -> Integer -> (Integer, Integer)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem
instance Integral Natural where
divMod :: Natural -> Natural -> (Natural, Natural)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
quotRem :: Natural -> Natural -> (Natural, Natural)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem
instance Integral Int8 where
divMod :: Int8 -> Int8 -> (Int8, Int8)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
quotRem :: Int8 -> Int8 -> (Int8, Int8)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem
instance Integral Int16 where
divMod :: Int16 -> Int16 -> (Int16, Int16)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
quotRem :: Int16 -> Int16 -> (Int16, Int16)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem
instance Integral Int32 where
divMod :: Int32 -> Int32 -> (Int32, Int32)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
quotRem :: Int32 -> Int32 -> (Int32, Int32)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem
instance Integral Int64 where
divMod :: Int64 -> Int64 -> (Int64, Int64)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
quotRem :: Int64 -> Int64 -> (Int64, Int64)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem
instance Integral Word where
divMod :: Word -> Word -> (Word, Word)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
quotRem :: Word -> Word -> (Word, Word)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem
instance Integral Word8 where
divMod :: Word8 -> Word8 -> (Word8, Word8)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
quotRem :: Word8 -> Word8 -> (Word8, Word8)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem
instance Integral Word16 where
divMod :: Word16 -> Word16 -> (Word16, Word16)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
quotRem :: Word16 -> Word16 -> (Word16, Word16)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem
instance Integral Word32 where
divMod :: Word32 -> Word32 -> (Word32, Word32)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
quotRem :: Word32 -> Word32 -> (Word32, Word32)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem
instance Integral Word64 where
divMod :: Word64 -> Word64 -> (Word64, Word64)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
quotRem :: Word64 -> Word64 -> (Word64, Word64)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem
instance (Integral b) => Integral (a -> b) where
div :: (a -> b) -> (a -> b) -> a -> b
div a -> b
f a -> b
f' a
a = a -> b
f a
a forall a. Integral a => a -> a -> a
`div` a -> b
f' a
a
mod :: (a -> b) -> (a -> b) -> a -> b
mod a -> b
f a -> b
f' a
a = a -> b
f a
a forall a. Integral a => a -> a -> a
`mod` a -> b
f' a
a
divMod :: (a -> b) -> (a -> b) -> (a -> b, a -> b)
divMod a -> b
f a -> b
f' = (\a
a -> forall a b. (a, b) -> a
fst (a -> b
f a
a forall a. Integral a => a -> a -> (a, a)
`divMod` a -> b
f' a
a), \a
a -> forall a b. (a, b) -> b
snd (a -> b
f a
a forall a. Integral a => a -> a -> (a, a)
`divMod` a -> b
f' a
a))
quot :: (a -> b) -> (a -> b) -> a -> b
quot a -> b
f a -> b
f' a
a = a -> b
f a
a forall a. Integral a => a -> a -> a
`mod` a -> b
f' a
a
rem :: (a -> b) -> (a -> b) -> a -> b
rem a -> b
f a -> b
f' a
a = a -> b
f a
a forall a. Integral a => a -> a -> a
`mod` a -> b
f' a
a
quotRem :: (a -> b) -> (a -> b) -> (a -> b, a -> b)
quotRem a -> b
f a -> b
f' = (\a
a -> forall a b. (a, b) -> a
fst (a -> b
f a
a forall a. Integral a => a -> a -> (a, a)
`quotRem` a -> b
f' a
a), \a
a -> forall a b. (a, b) -> b
snd (a -> b
f a
a forall a. Integral a => a -> a -> (a, a)
`quotRem` a -> b
f' a
a))
class ToIntegral a b where
{-# MINIMAL toIntegral #-}
toIntegral :: a -> b
instance ToIntegral Integer Integer where
toIntegral :: Integer -> Integer
toIntegral = forall a. a -> a
P.id
instance ToIntegral Int Integer where
toIntegral :: Int -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger
instance ToIntegral Natural Integer where
toIntegral :: Natural -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger
instance ToIntegral Int8 Integer where
toIntegral :: Int8 -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger
instance ToIntegral Int16 Integer where
toIntegral :: Int16 -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger
instance ToIntegral Int32 Integer where
toIntegral :: Int32 -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger
instance ToIntegral Int64 Integer where
toIntegral :: Int64 -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger
instance ToIntegral Word Integer where
toIntegral :: Word -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger
instance ToIntegral Word8 Integer where
toIntegral :: Word8 -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger
instance ToIntegral Word16 Integer where
toIntegral :: Word16 -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger
instance ToIntegral Word32 Integer where
toIntegral :: Word32 -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger
instance ToIntegral Word64 Integer where
toIntegral :: Word64 -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger
instance ToIntegral Int Int where
toIntegral :: Int -> Int
toIntegral = forall a. a -> a
P.id
instance ToIntegral Integer Int where
toIntegral :: Integer -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance ToIntegral Natural Int where
toIntegral :: Natural -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance ToIntegral Int8 Int where
toIntegral :: Int8 -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance ToIntegral Int16 Int where
toIntegral :: Int16 -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance ToIntegral Int32 Int where
toIntegral :: Int32 -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance ToIntegral Int64 Int where
toIntegral :: Int64 -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance ToIntegral Word Int where
toIntegral :: Word -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance ToIntegral Word8 Int where
toIntegral :: Word8 -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance ToIntegral Word16 Int where
toIntegral :: Word16 -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance ToIntegral Word32 Int where
toIntegral :: Word32 -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance ToIntegral Word64 Int where
toIntegral :: Word64 -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance ToIntegral Natural Natural where
toIntegral :: Natural -> Natural
toIntegral = forall a. a -> a
P.id
instance ToIntegral Int8 Int8 where
toIntegral :: Int8 -> Int8
toIntegral = forall a. a -> a
P.id
instance ToIntegral Int16 Int16 where
toIntegral :: Int16 -> Int16
toIntegral = forall a. a -> a
P.id
instance ToIntegral Int32 Int32 where
toIntegral :: Int32 -> Int32
toIntegral = forall a. a -> a
P.id
instance ToIntegral Int64 Int64 where
toIntegral :: Int64 -> Int64
toIntegral = forall a. a -> a
P.id
instance ToIntegral Word Word where
toIntegral :: Word -> Word
toIntegral = forall a. a -> a
P.id
instance ToIntegral Word8 Word8 where
toIntegral :: Word8 -> Word8
toIntegral = forall a. a -> a
P.id
instance ToIntegral Word16 Word16 where
toIntegral :: Word16 -> Word16
toIntegral = forall a. a -> a
P.id
instance ToIntegral Word32 Word32 where
toIntegral :: Word32 -> Word32
toIntegral = forall a. a -> a
P.id
instance ToIntegral Word64 Word64 where
toIntegral :: Word64 -> Word64
toIntegral = forall a. a -> a
P.id
class FromIntegral a b where
{-# MINIMAL fromIntegral #-}
fromIntegral :: b -> a
instance (FromIntegral a b) => FromIntegral (c -> a) b where
fromIntegral :: b -> c -> a
fromIntegral b
i c
_ = forall a b. FromIntegral a b => b -> a
fromIntegral b
i
instance FromIntegral Double Integer where
fromIntegral :: Integer -> Double
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger
instance FromIntegral Float Integer where
fromIntegral :: Integer -> Float
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger
instance FromIntegral Int Integer where
fromIntegral :: Integer -> Int
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger
instance FromIntegral Integer Integer where
fromIntegral :: Integer -> Integer
fromIntegral = forall a. a -> a
P.id
instance FromIntegral Natural Integer where
fromIntegral :: Integer -> Natural
fromIntegral = Integer -> Natural
naturalFromInteger
instance FromIntegral Int8 Integer where
fromIntegral :: Integer -> Int8
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger
instance FromIntegral Int16 Integer where
fromIntegral :: Integer -> Int16
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger
instance FromIntegral Int32 Integer where
fromIntegral :: Integer -> Int32
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger
instance FromIntegral Int64 Integer where
fromIntegral :: Integer -> Int64
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger
instance FromIntegral Word Integer where
fromIntegral :: Integer -> Word
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger
instance FromIntegral Word8 Integer where
fromIntegral :: Integer -> Word8
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger
instance FromIntegral Word16 Integer where
fromIntegral :: Integer -> Word16
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger
instance FromIntegral Word32 Integer where
fromIntegral :: Integer -> Word32
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger
instance FromIntegral Word64 Integer where
fromIntegral :: Integer -> Word64
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger
instance FromIntegral Double Int where
fromIntegral :: Int -> Double
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance FromIntegral Float Int where
fromIntegral :: Int -> Float
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance FromIntegral Int Int where
fromIntegral :: Int -> Int
fromIntegral = forall a. a -> a
P.id
instance FromIntegral Integer Int where
fromIntegral :: Int -> Integer
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance FromIntegral Natural Int where
fromIntegral :: Int -> Natural
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance FromIntegral Int8 Int where
fromIntegral :: Int -> Int8
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance FromIntegral Int16 Int where
fromIntegral :: Int -> Int16
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance FromIntegral Int32 Int where
fromIntegral :: Int -> Int32
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance FromIntegral Int64 Int where
fromIntegral :: Int -> Int64
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance FromIntegral Word Int where
fromIntegral :: Int -> Word
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance FromIntegral Word8 Int where
fromIntegral :: Int -> Word8
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance FromIntegral Word16 Int where
fromIntegral :: Int -> Word16
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance FromIntegral Word32 Int where
fromIntegral :: Int -> Word32
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance FromIntegral Word64 Int where
fromIntegral :: Int -> Word64
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
instance FromIntegral Natural Natural where
fromIntegral :: Natural -> Natural
fromIntegral = forall a. a -> a
P.id
instance FromIntegral Int8 Int8 where
fromIntegral :: Int8 -> Int8
fromIntegral = forall a. a -> a
P.id
instance FromIntegral Int16 Int16 where
fromIntegral :: Int16 -> Int16
fromIntegral = forall a. a -> a
P.id
instance FromIntegral Int32 Int32 where
fromIntegral :: Int32 -> Int32
fromIntegral = forall a. a -> a
P.id
instance FromIntegral Int64 Int64 where
fromIntegral :: Int64 -> Int64
fromIntegral = forall a. a -> a
P.id
instance FromIntegral Word Word where
fromIntegral :: Word -> Word
fromIntegral = forall a. a -> a
P.id
instance FromIntegral Word8 Word8 where
fromIntegral :: Word8 -> Word8
fromIntegral = forall a. a -> a
P.id
instance FromIntegral Word16 Word16 where
fromIntegral :: Word16 -> Word16
fromIntegral = forall a. a -> a
P.id
instance FromIntegral Word32 Word32 where
fromIntegral :: Word32 -> Word32
fromIntegral = forall a. a -> a
P.id
instance FromIntegral Word64 Word64 where
fromIntegral :: Word64 -> Word64
fromIntegral = forall a. a -> a
P.id
class FromInteger a where
fromInteger :: Integer -> a
instance FromInteger Double where
fromInteger :: Integer -> Double
fromInteger = forall a. Num a => Integer -> a
P.fromInteger
instance FromInteger Float where
fromInteger :: Integer -> Float
fromInteger = forall a. Num a => Integer -> a
P.fromInteger
instance FromInteger Int where
fromInteger :: Integer -> Int
fromInteger = forall a. Num a => Integer -> a
P.fromInteger
instance FromInteger Integer where
fromInteger :: Integer -> Integer
fromInteger = forall a. a -> a
P.id
instance FromInteger Natural where
fromInteger :: Integer -> Natural
fromInteger = Integer -> Natural
naturalFromInteger
instance FromInteger Int8 where
fromInteger :: Integer -> Int8
fromInteger = forall a. Num a => Integer -> a
P.fromInteger
instance FromInteger Int16 where
fromInteger :: Integer -> Int16
fromInteger = forall a. Num a => Integer -> a
P.fromInteger
instance FromInteger Int32 where
fromInteger :: Integer -> Int32
fromInteger = forall a. Num a => Integer -> a
P.fromInteger
instance FromInteger Int64 where
fromInteger :: Integer -> Int64
fromInteger = forall a. Num a => Integer -> a
P.fromInteger
instance FromInteger Word where
fromInteger :: Integer -> Word
fromInteger = forall a. Num a => Integer -> a
P.fromInteger
instance FromInteger Word8 where
fromInteger :: Integer -> Word8
fromInteger = forall a. Num a => Integer -> a
P.fromInteger
instance FromInteger Word16 where
fromInteger :: Integer -> Word16
fromInteger = forall a. Num a => Integer -> a
P.fromInteger
instance FromInteger Word32 where
fromInteger :: Integer -> Word32
fromInteger = forall a. Num a => Integer -> a
P.fromInteger
instance FromInteger Word64 where
fromInteger :: Integer -> Word64
fromInteger = forall a. Num a => Integer -> a
P.fromInteger
even :: (P.Eq a, Integral a) => a -> P.Bool
even :: forall a. (Eq a, Integral a) => a -> Bool
even a
n = a
n forall a. Integral a => a -> a -> a
`rem` (forall a. Multiplicative a => a
one forall a. Additive a => a -> a -> a
+ forall a. Multiplicative a => a
one) forall a. Eq a => a -> a -> Bool
P.== forall a. Additive a => a
zero
odd :: (P.Eq a, Integral a) => a -> P.Bool
odd :: forall a. (Eq a, Integral a) => a -> Bool
odd = Bool -> Bool
P.not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (Eq a, Integral a) => a -> Bool
even
infixr 8 ^^
(^^) ::
(P.Ord b, Divisive a, Subtractive b, Integral b) =>
a ->
b ->
a
a
x0 ^^ :: forall b a.
(Ord b, Divisive a, Subtractive b, Integral b) =>
a -> b -> a
^^ b
y0 =
case forall a. Ord a => a -> a -> Ordering
compare b
y0 forall a. Additive a => a
zero of
Ordering
EQ -> forall a. Multiplicative a => a
one
Ordering
GT -> forall {a} {t}. (Eq a, Integral a, Multiplicative t) => t -> a -> t
f a
x0 b
y0
Ordering
LT -> forall a. Divisive a => a -> a
recip (a
x0 forall b a.
(Ord b, Divisive a, Subtractive b, Integral b) =>
a -> b -> a
^^ forall a. Subtractive a => a -> a
negate b
y0)
where
f :: t -> a -> t
f t
x a
y
| forall a. (Eq a, Integral a) => a -> Bool
even a
y = t -> a -> t
f (t
x forall a. Multiplicative a => a -> a -> a
* t
x) (a
y forall a. Integral a => a -> a -> a
`quot` forall a. (Multiplicative a, Additive a) => a
two)
| a
y forall a. Eq a => a -> a -> Bool
P.== forall a. Multiplicative a => a
one = t
x
| Bool
P.otherwise = forall {a} {t}.
(Eq a, Integral a, Multiplicative t) =>
t -> a -> t -> t
g (t
x forall a. Multiplicative a => a -> a -> a
* t
x) (a
y forall a. Integral a => a -> a -> a
`quot` forall a. (Multiplicative a, Additive a) => a
two) t
x
g :: t -> a -> t -> t
g t
x a
y t
z
| forall a. (Eq a, Integral a) => a -> Bool
even a
y = t -> a -> t -> t
g (t
x forall a. Multiplicative a => a -> a -> a
* t
x) (a
y forall a. Integral a => a -> a -> a
`quot` forall a. (Multiplicative a, Additive a) => a
two) t
z
| a
y forall a. Eq a => a -> a -> Bool
P.== forall a. Multiplicative a => a
one = t
x forall a. Multiplicative a => a -> a -> a
* t
z
| Bool
P.otherwise = t -> a -> t -> t
g (t
x forall a. Multiplicative a => a -> a -> a
* t
x) (a
y forall a. Integral a => a -> a -> a
`quot` forall a. (Multiplicative a, Additive a) => a
two) (t
x forall a. Multiplicative a => a -> a -> a
* t
z)
infixr 8 ^
(^) ::
(Divisive a) => a -> Int -> a
^ :: forall a. Divisive a => a -> Int -> a
(^) a
x Int
n = a
x forall b a.
(Ord b, Divisive a, Subtractive b, Integral b) =>
a -> b -> a
^^ Int
n