module Integer.Positive
(
Positive,
toNatural,
fromNatural,
toInteger,
fromInteger,
toSigned,
fromSigned,
toInt,
fromInt,
toWord,
fromWord,
subtract,
increase,
one,
addOne,
subtractOne,
length,
)
where
import Data.Int (Int)
import Data.List qualified as List
import Data.List.NonEmpty (NonEmpty (..))
import Data.Ord qualified as Ord
import Data.Word (Word)
import Essentials
import Integer.Positive.Unsafe (Positive, addOne, increase, one, toInteger, toNatural)
import Integer.Positive.Unsafe qualified as Unsafe
import Integer.Signed (Signed (..))
import Numeric.Natural (Natural)
import Prelude (Integer)
import Prelude qualified as Bounded (Bounded (..))
import Prelude qualified as Num (Integral (..), Num (..))
fromInteger :: Integer -> Maybe Positive
fromInteger :: Integer -> Maybe Positive
fromInteger Integer
x = if Integer
x Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
Ord.> Integer
0 then Positive -> Maybe Positive
forall a. a -> Maybe a
Just (Integer -> Positive
Unsafe.fromInteger Integer
x) else Maybe Positive
forall a. Maybe a
Nothing
fromNatural :: Natural -> Maybe Positive
fromNatural :: Natural -> Maybe Positive
fromNatural Natural
x = case Natural
x of Natural
0 -> Maybe Positive
forall a. Maybe a
Nothing; Natural
_ -> Positive -> Maybe Positive
forall a. a -> Maybe a
Just (Natural -> Positive
Unsafe.fromNatural Natural
x)
toInt :: Positive -> Maybe Int
toInt :: Positive -> Maybe Int
toInt Positive
x = if Bool
ok then Int -> Maybe Int
forall a. a -> Maybe a
Just (Integer -> Int
forall a. Num a => Integer -> a
Num.fromInteger Integer
x') else Maybe Int
forall a. Maybe a
Nothing
where
ok :: Bool
ok = Integer
x' Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
Ord.<= Int -> Integer
forall a. Integral a => a -> Integer
Num.toInteger (Int
forall a. Bounded a => a
Bounded.maxBound :: Int)
x' :: Integer
x' = Positive -> Integer
forall a. Integral a => a -> Integer
Num.toInteger Positive
x
fromInt :: Int -> Maybe Positive
fromInt :: Int -> Maybe Positive
fromInt Int
x = if Bool
ok then Positive -> Maybe Positive
forall a. a -> Maybe a
Just (Integer -> Positive
forall a. Num a => Integer -> a
Num.fromInteger Integer
x') else Maybe Positive
forall a. Maybe a
Nothing
where
ok :: Bool
ok = Integer
x' Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
Ord.>= Integer
1
x' :: Integer
x' = Int -> Integer
forall a. Integral a => a -> Integer
Num.toInteger Int
x
toWord :: Positive -> Maybe Word
toWord :: Positive -> Maybe Word
toWord Positive
x = if Bool
ok then Word -> Maybe Word
forall a. a -> Maybe a
Just (Integer -> Word
forall a. Num a => Integer -> a
Num.fromInteger Integer
x') else Maybe Word
forall a. Maybe a
Nothing
where
ok :: Bool
ok = Integer
x' Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
Ord.<= Word -> Integer
forall a. Integral a => a -> Integer
Num.toInteger (Word
forall a. Bounded a => a
Bounded.maxBound :: Word)
x' :: Integer
x' = Positive -> Integer
forall a. Integral a => a -> Integer
Num.toInteger Positive
x
fromWord :: Word -> Maybe Positive
fromWord :: Word -> Maybe Positive
fromWord Word
x = if Bool
ok then Positive -> Maybe Positive
forall a. a -> Maybe a
Just (Integer -> Positive
forall a. Num a => Integer -> a
Num.fromInteger Integer
x') else Maybe Positive
forall a. Maybe a
Nothing
where
ok :: Bool
ok = Integer
x' Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
Ord.>= Integer
1
x' :: Integer
x' = Word -> Integer
forall a. Integral a => a -> Integer
Num.toInteger Word
x
subtract :: Positive -> Positive -> Signed
subtract :: Positive -> Positive -> Signed
subtract Positive
a Positive
b = case Positive -> Positive -> Ordering
forall a. Ord a => a -> a -> Ordering
Ord.compare Positive
a Positive
b of
Ordering
Ord.EQ -> Signed
Zero
Ordering
Ord.GT -> Positive -> Signed
Plus (Positive -> Signed) -> Positive -> Signed
forall a b. (a -> b) -> a -> b
$ Positive -> Positive -> Positive
Unsafe.subtract Positive
a Positive
b
Ordering
Ord.LT -> Positive -> Signed
Minus (Positive -> Signed) -> Positive -> Signed
forall a b. (a -> b) -> a -> b
$ Positive -> Positive -> Positive
Unsafe.subtract Positive
b Positive
a
subtractOne :: Positive -> Natural
subtractOne :: Positive -> Natural
subtractOne Positive
x = Positive -> Natural
toNatural Positive
x Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
Num.- Natural
1
toSigned :: Positive -> Signed
toSigned :: Positive -> Signed
toSigned = Positive -> Signed
Plus
fromSigned :: Signed -> Maybe Positive
fromSigned :: Signed -> Maybe Positive
fromSigned (Plus Positive
x) = Positive -> Maybe Positive
forall a. a -> Maybe a
Just Positive
x
fromSigned Signed
_ = Maybe Positive
forall a. Maybe a
Nothing
length :: NonEmpty a -> Positive
length :: forall a. NonEmpty a -> Positive
length (a
_ :| [a]
xs) = (Positive -> a -> Positive) -> Positive -> [a] -> Positive
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' (\Positive
x a
_ -> Positive
x Positive -> Positive -> Positive
forall a. Num a => a -> a -> a
Num.+ Positive
1) Positive
1 [a]
xs