module Data.Type.Equality (
  
  (:~:)(..),
  
  
  sym, trans, castWith, gcastWith, apply, inner, outer,
  
  TestEquality(..),
  
  type (==)
  ) where
import Data.Maybe
import GHC.Enum
import GHC.Show
import GHC.Read
import GHC.Base
import Data.Type.Bool
infix 4 :~:
data a :~: b where
  Refl :: a :~: a
sym :: (a :~: b) -> (b :~: a)
sym Refl = Refl
trans :: (a :~: b) -> (b :~: c) -> (a :~: c)
trans Refl Refl = Refl
castWith :: (a :~: b) -> a -> b
castWith Refl x = x
gcastWith :: (a :~: b) -> ((a ~ b) => r) -> r
gcastWith Refl x = x
apply :: (f :~: g) -> (a :~: b) -> (f a :~: g b)
apply Refl Refl = Refl
inner :: (f a :~: g b) -> (a :~: b)
inner Refl = Refl
outer :: (f a :~: g b) -> (f :~: g)
outer Refl = Refl
deriving instance Eq   (a :~: b)
deriving instance Show (a :~: b)
deriving instance Ord  (a :~: b)
instance a ~ b => Read (a :~: b) where
  readsPrec d = readParen (d > 10) (\r -> [(Refl, s) | ("Refl",s) <- lex r ])
instance a ~ b => Enum (a :~: b) where
  toEnum 0 = Refl
  toEnum _ = error "Data.Type.Equality.toEnum: bad argument"
  fromEnum Refl = 0
instance a ~ b => Bounded (a :~: b) where
  minBound = Refl
  maxBound = Refl
class TestEquality f where
  
  testEquality :: f a -> f b -> Maybe (a :~: b)
instance TestEquality ((:~:) a) where
  testEquality Refl Refl = Just Refl
type family (a :: k) == (b :: k) :: Bool
infix 4 ==
type family EqStar (a :: *) (b :: *) where
  EqStar a a = 'True
  EqStar a b = 'False
type family EqArrow (a :: k1 -> k2) (b :: k1 -> k2) where
  EqArrow a a = 'True
  EqArrow a b = 'False
type family EqBool a b where
  EqBool 'True  'True  = 'True
  EqBool 'False 'False = 'True
  EqBool a     b       = 'False
type family EqOrdering a b where
  EqOrdering 'LT 'LT = 'True
  EqOrdering 'EQ 'EQ = 'True
  EqOrdering 'GT 'GT = 'True
  EqOrdering a  b    = 'False
type EqUnit (a :: ()) (b :: ()) = 'True
type family EqList a b where
  EqList '[]        '[]        = 'True
  EqList (h1 ': t1) (h2 ': t2) = (h1 == h2) && (t1 == t2)
  EqList a          b          = 'False
type family EqMaybe a b where
  EqMaybe 'Nothing   'Nothing  = 'True
  EqMaybe ('Just x) ('Just y)  = x == y
  EqMaybe a        b           = 'False
type family Eq2 a b where
  Eq2 '(a1, b1) '(a2, b2) = a1 == a2 && b1 == b2
type family Eq3 a b where
  Eq3 '(a1, b1, c1) '(a2, b2, c2) = a1 == a2 && b1 == b2 && c1 == c2
type family Eq4 a b where
  Eq4 '(a1, b1, c1, d1) '(a2, b2, c2, d2) = a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2
type family Eq5 a b where
  Eq5 '(a1, b1, c1, d1, e1) '(a2, b2, c2, d2, e2) = a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2 && e1 == e2
type family Eq6 a b where
  Eq6 '(a1, b1, c1, d1, e1, f1) '(a2, b2, c2, d2, e2, f2) = a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2 && e1 == e2 && f1 == f2
type family Eq7 a b where
  Eq7 '(a1, b1, c1, d1, e1, f1, g1) '(a2, b2, c2, d2, e2, f2, g2) = a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2 && e1 == e2 && f1 == f2 && g1 == g2
type family Eq8 a b where
  Eq8 '(a1, b1, c1, d1, e1, f1, g1, h1) '(a2, b2, c2, d2, e2, f2, g2, h2) = a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2 && e1 == e2 && f1 == f2 && g1 == g2 && h1 == h2
type family Eq9 a b where
  Eq9 '(a1, b1, c1, d1, e1, f1, g1, h1, i1) '(a2, b2, c2, d2, e2, f2, g2, h2, i2) = a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2 && e1 == e2 && f1 == f2 && g1 == g2 && h1 == h2 && i1 == i2
type family Eq10 a b where
  Eq10 '(a1, b1, c1, d1, e1, f1, g1, h1, i1, j1) '(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2) = a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2 && e1 == e2 && f1 == f2 && g1 == g2 && h1 == h2 && i1 == i2 && j1 == j2
type family Eq11 a b where
  Eq11 '(a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1) '(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2) = a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2 && e1 == e2 && f1 == f2 && g1 == g2 && h1 == h2 && i1 == i2 && j1 == j2 && k1 == k2
type family Eq12 a b where
  Eq12 '(a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1) '(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2) = a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2 && e1 == e2 && f1 == f2 && g1 == g2 && h1 == h2 && i1 == i2 && j1 == j2 && k1 == k2 && l1 == l2
type family Eq13 a b where
  Eq13 '(a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1) '(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2) = a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2 && e1 == e2 && f1 == f2 && g1 == g2 && h1 == h2 && i1 == i2 && j1 == j2 && k1 == k2 && l1 == l2 && m1 == m2
type family Eq14 a b where
  Eq14 '(a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1) '(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2) = a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2 && e1 == e2 && f1 == f2 && g1 == g2 && h1 == h2 && i1 == i2 && j1 == j2 && k1 == k2 && l1 == l2 && m1 == m2 && n1 == n2
type family Eq15 a b where
  Eq15 '(a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1) '(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2) = a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2 && e1 == e2 && f1 == f2 && g1 == g2 && h1 == h2 && i1 == i2 && j1 == j2 && k1 == k2 && l1 == l2 && m1 == m2 && n1 == n2 && o1 == o2
type instance a == b = EqStar a b
type instance a == b = EqArrow a b
type instance a == b = EqBool a b
type instance a == b = EqOrdering a b
type instance a == b = EqUnit a b
type instance a == b = EqList a b
type instance a == b = EqMaybe a b
type instance a == b = Eq2 a b
type instance a == b = Eq3 a b
type instance a == b = Eq4 a b
type instance a == b = Eq5 a b
type instance a == b = Eq6 a b
type instance a == b = Eq7 a b
type instance a == b = Eq8 a b
type instance a == b = Eq9 a b
type instance a == b = Eq10 a b
type instance a == b = Eq11 a b
type instance a == b = Eq12 a b
type instance a == b = Eq13 a b
type instance a == b = Eq14 a b
type instance a == b = Eq15 a b