module Integer.Integer
  ( -- * Type
    Integer,

    -- * Conversion

    -- ** Positive
    toPositive,
    fromPositive,

    -- ** Natural
    toNatural,
    fromNatural,

    -- ** Signed
    toSigned,
    fromSigned,

    -- ** Int
    toInt,
    fromInt,

    -- ** Word
    toWord,
    fromWord,

    -- * Arithmetic

    -- ** Increase
    increase,
    strictlyIncrease,
  )
where

import Data.Bool qualified as Bool
import Data.Int (Int)
import Data.Ord qualified as Ord
import Data.Word (Word)
import Essentials
import Integer.Natural qualified as Natural
import Integer.Positive (Positive)
import Integer.Positive qualified as Positive
import Integer.Signed (Signed (..))
import Integer.Signed qualified as Signed
import Numeric.Natural (Natural)
import Prelude (Integer)
import Prelude qualified as Bounded (Bounded (..))
import Prelude qualified as Num (Integral (..), Num (..))

toPositive :: Integer -> Maybe Positive
toPositive :: Integer -> Maybe Positive
toPositive = Integer -> Maybe Positive
Positive.fromInteger

fromPositive :: Positive -> Integer
fromPositive :: Positive -> Integer
fromPositive = Positive -> Integer
Positive.toInteger

toNatural :: Integer -> Maybe Natural
toNatural :: Integer -> Maybe Natural
toNatural = Integer -> Maybe Natural
Natural.fromInteger

fromNatural :: Natural -> Integer
fromNatural :: Natural -> Integer
fromNatural = Natural -> Integer
Natural.toInteger

toSigned :: Integer -> Signed
toSigned :: Integer -> Signed
toSigned = Integer -> Signed
Signed.fromInteger

fromSigned :: Signed -> Integer
fromSigned :: Signed -> Integer
fromSigned = Signed -> Integer
Signed.toInteger

toInt :: Integer -> Maybe Int
toInt :: Integer -> Maybe Int
toInt Integer
x = if Bool
ok then forall a. a -> Maybe a
Just (forall a. Num a => Integer -> a
Num.fromInteger Integer
x) else forall a. Maybe a
Nothing
  where
    ok :: Bool
ok =
      Integer
x forall a. Ord a => a -> a -> Bool
Ord.>= forall a. Integral a => a -> Integer
Num.toInteger (forall a. Bounded a => a
Bounded.minBound :: Int)
        Bool -> Bool -> Bool
Bool.&& Integer
x forall a. Ord a => a -> a -> Bool
Ord.<= forall a. Integral a => a -> Integer
Num.toInteger (forall a. Bounded a => a
Bounded.maxBound :: Int)

fromInt :: Int -> Integer
fromInt :: Int -> Integer
fromInt = forall a. Integral a => a -> Integer
Num.toInteger

toWord :: Integer -> Maybe Word
toWord :: Integer -> Maybe Word
toWord Integer
x = if Bool
ok then forall a. a -> Maybe a
Just (forall a. Num a => Integer -> a
Num.fromInteger Integer
x) else forall a. Maybe a
Nothing
  where
    ok :: Bool
ok =
      Integer
x forall a. Ord a => a -> a -> Bool
Ord.>= forall a. Integral a => a -> Integer
Num.toInteger (forall a. Bounded a => a
Bounded.minBound :: Word)
        Bool -> Bool -> Bool
Bool.&& Integer
x forall a. Ord a => a -> a -> Bool
Ord.<= forall a. Integral a => a -> Integer
Num.toInteger (forall a. Bounded a => a
Bounded.maxBound :: Word)

fromWord :: Word -> Integer
fromWord :: Word -> Integer
fromWord = forall a. Integral a => a -> Integer
Num.toInteger

increase :: Natural -> Integer -> Integer
increase :: Natural -> Integer -> Integer
increase Natural
n = forall a. Num a => a -> a -> a
(Num.+) (Natural -> Integer
fromNatural Natural
n)

strictlyIncrease :: Positive -> Integer -> Integer
strictlyIncrease :: Positive -> Integer -> Integer
strictlyIncrease Positive
n = forall a. Num a => a -> a -> a
(Num.+) (Positive -> Integer
fromPositive Positive
n)