module Integer.Conversion
  (
    IntegerNarrow (narrow),
    IntegerConvert (convert),
    IntegerEquiv,
    yolo,
  )
  where

import Essentials

import Integer.Integer (Integer)
import Integer.Natural (Natural)
import Integer.Positive (Positive)
import Integer.Signed (Signed)

import qualified Integer.Integer as Integer
import qualified Integer.Natural as Natural
import qualified Integer.Positive as Positive
import qualified Integer.Signed as Signed
import qualified Prelude as Num (Integral (..), Num (..))

class IntegerNarrow a b => IntegerConvert a b where
    convert :: a -> b

class IntegerNarrow a b where
    narrow :: a -> Maybe b

class (IntegerConvert a b, IntegerConvert b a) => IntegerEquiv a b


---  Isomorphisms  ---

instance IntegerEquiv   Integer  Integer
instance IntegerConvert Integer  Integer  where convert :: Integer -> Integer
convert = forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
instance IntegerNarrow  Integer  Integer  where narrow :: Integer -> Maybe Integer
narrow = forall a. a -> Maybe a
Just

instance IntegerEquiv   Natural  Natural
instance IntegerConvert Natural  Natural  where convert :: Natural -> Natural
convert = forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
instance IntegerNarrow  Natural  Natural  where narrow :: Natural -> Maybe Natural
narrow  = forall a. a -> Maybe a
Just

instance IntegerEquiv   Positive Positive
instance IntegerConvert Positive Positive where convert :: Positive -> Positive
convert = forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
instance IntegerNarrow  Positive Positive where narrow :: Positive -> Maybe Positive
narrow  = forall a. a -> Maybe a
Just

instance IntegerEquiv   Signed   Signed
instance IntegerConvert Signed   Signed   where convert :: Signed -> Signed
convert = forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
instance IntegerNarrow  Signed   Signed   where narrow :: Signed -> Maybe Signed
narrow  = forall a. a -> Maybe a
Just

instance IntegerEquiv   Integer  Signed
instance IntegerConvert Integer  Signed   where convert :: Integer -> Signed
convert = Integer -> Signed
Integer.toSigned
instance IntegerNarrow  Integer  Signed   where narrow :: Integer -> Maybe Signed
narrow  = forall a. a -> Maybe a
Just forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a b. IntegerConvert a b => a -> b
convert

instance IntegerEquiv   Signed   Integer
instance IntegerConvert Signed   Integer  where convert :: Signed -> Integer
convert = Signed -> Integer
Signed.toInteger
instance IntegerNarrow  Signed   Integer  where narrow :: Signed -> Maybe Integer
narrow  = forall a. a -> Maybe a
Just forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a b. IntegerConvert a b => a -> b
convert


---  Prisms  ---

instance IntegerNarrow  Integer  Natural  where narrow :: Integer -> Maybe Natural
narrow  = Integer -> Maybe Natural
Integer.toNatural
instance IntegerNarrow  Natural  Integer  where narrow :: Natural -> Maybe Integer
narrow  = forall a. a -> Maybe a
Just forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a b. IntegerConvert a b => a -> b
convert
instance IntegerConvert Natural  Integer  where convert :: Natural -> Integer
convert = Natural -> Integer
Natural.toInteger

instance IntegerNarrow  Signed   Natural  where narrow :: Signed -> Maybe Natural
narrow  = Signed -> Maybe Natural
Signed.toNatural
instance IntegerNarrow  Natural  Signed   where narrow :: Natural -> Maybe Signed
narrow  = forall a. a -> Maybe a
Just forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a b. IntegerConvert a b => a -> b
convert
instance IntegerConvert Natural  Signed   where convert :: Natural -> Signed
convert = Natural -> Signed
Natural.toSigned

instance IntegerNarrow  Integer  Positive where narrow :: Integer -> Maybe Positive
narrow  = Integer -> Maybe Positive
Integer.toPositive
instance IntegerNarrow  Positive Integer  where narrow :: Positive -> Maybe Integer
narrow  = forall a. a -> Maybe a
Just forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a b. IntegerConvert a b => a -> b
convert
instance IntegerConvert Positive Integer  where convert :: Positive -> Integer
convert = Positive -> Integer
Positive.toInteger

instance IntegerNarrow  Natural  Positive where narrow :: Natural -> Maybe Positive
narrow  = Natural -> Maybe Positive
Natural.toPositive
instance IntegerNarrow  Positive Natural  where narrow :: Positive -> Maybe Natural
narrow  = forall a. a -> Maybe a
Just forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a b. IntegerConvert a b => a -> b
convert
instance IntegerConvert Positive Natural  where convert :: Positive -> Natural
convert = Positive -> Natural
Positive.toNatural

instance IntegerNarrow  Signed   Positive where narrow :: Signed -> Maybe Positive
narrow  = Signed -> Maybe Positive
Signed.toPositive
instance IntegerNarrow  Positive Signed   where narrow :: Positive -> Maybe Signed
narrow  = forall a. a -> Maybe a
Just forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a b. IntegerConvert a b => a -> b
convert
instance IntegerConvert Positive Signed   where convert :: Positive -> Signed
convert = Positive -> Signed
Positive.toSigned


---  lol  ---

-- | Partial conversion between 'Num.Integral' types via 'Integer'
--
-- @
-- yolo = 'Num.fromInteger' . 'Num.toInteger'
-- @
--
yolo :: (Num.Integral a, Num.Num b) => a -> b
yolo :: forall a b. (Integral a, Num b) => a -> b
yolo = forall a. Num a => Integer -> a
Num.fromInteger forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a. Integral a => a -> Integer
Num.toInteger