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

import Essentials
import Integer.Integer (Integer)
import Integer.Integer qualified as Integer
import Integer.Natural (Natural)
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 Prelude qualified 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