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 = Integer -> Integer
forall a. a -> a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id

instance IntegerNarrow Integer Integer where narrow :: Integer -> Maybe Integer
narrow = Integer -> Maybe Integer
forall a. a -> Maybe a
Just

instance IntegerEquiv Natural Natural

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

instance IntegerNarrow Natural Natural where narrow :: Natural -> Maybe Natural
narrow = Natural -> Maybe Natural
forall a. a -> Maybe a
Just

instance IntegerEquiv Positive Positive

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

instance IntegerNarrow Positive Positive where narrow :: Positive -> Maybe Positive
narrow = Positive -> Maybe Positive
forall a. a -> Maybe a
Just

instance IntegerEquiv Signed Signed

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

instance IntegerNarrow Signed Signed where narrow :: Signed -> Maybe Signed
narrow = Signed -> Maybe Signed
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 = Signed -> Maybe Signed
forall a. a -> Maybe a
Just (Signed -> Maybe Signed)
-> (Integer -> Signed) -> Integer -> Maybe Signed
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Integer -> Signed
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 = Integer -> Maybe Integer
forall a. a -> Maybe a
Just (Integer -> Maybe Integer)
-> (Signed -> Integer) -> Signed -> Maybe Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Signed -> Integer
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 = Integer -> Maybe Integer
forall a. a -> Maybe a
Just (Integer -> Maybe Integer)
-> (Natural -> Integer) -> Natural -> Maybe Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Natural -> Integer
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 = Signed -> Maybe Signed
forall a. a -> Maybe a
Just (Signed -> Maybe Signed)
-> (Natural -> Signed) -> Natural -> Maybe Signed
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Natural -> Signed
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 = Integer -> Maybe Integer
forall a. a -> Maybe a
Just (Integer -> Maybe Integer)
-> (Positive -> Integer) -> Positive -> Maybe Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Positive -> Integer
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 = Natural -> Maybe Natural
forall a. a -> Maybe a
Just (Natural -> Maybe Natural)
-> (Positive -> Natural) -> Positive -> Maybe Natural
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Positive -> Natural
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 = Signed -> Maybe Signed
forall a. a -> Maybe a
Just (Signed -> Maybe Signed)
-> (Positive -> Signed) -> Positive -> Maybe Signed
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Positive -> Signed
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 = Integer -> b
forall a. Num a => Integer -> a
Num.fromInteger (Integer -> b) -> (a -> Integer) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> Integer
forall a. Integral a => a -> Integer
Num.toInteger