{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ImpredicativeTypes #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Universe (
Shaped (..),
Singleton (..),
Universe (..),
Any (..),
Some (..),
Dyn (..),
Shape (..),
Eql,
(:~:) (Refl),
TypeRep,
compareByShape,
)
where
import Data.Kind (Type)
import Data.Type.Equality (TestEquality (..), (:~:) (Refl))
#if __GLASGOW_HASKELL__ < 906
import Type.Reflection (TypeRep, pattern App, pattern Con, pattern Fun)
#else
import Type.Reflection (TypeRep, pattern App, pattern Con)
#endif
type Eql x y = x :~: y
class Singleton t where
testEql :: t i -> t j -> Maybe (i :~: j)
cmpIndex :: t a -> t b -> Ordering
class Shaped t rep where
shape :: t i -> Shape rep
compareByShape ::
forall (rep :: Type -> Type) (t :: Type -> Type) (i :: Type) (j :: Type).
Shaped t rep =>
t i ->
t j ->
Ordering
compareByShape :: forall (rep :: * -> *) (t :: * -> *) i j.
Shaped t rep =>
t i -> t j -> Ordering
compareByShape t i
x t j
y = forall a. Ord a => a -> a -> Ordering
compare (forall {k} (t :: k -> *) (rep :: * -> *) (i :: k).
Shaped t rep =>
t i -> Shape rep
shape @t @rep t i
x) (forall {k} (t :: k -> *) (rep :: * -> *) (i :: k).
Shaped t rep =>
t i -> Shape rep
shape @t @rep t j
y)
class Singleton rep => Universe rep t where
repOf :: rep t
data Any t where
Any :: t i -> Any t
deriving instance (forall i. Show (t i)) => Show (Any t)
data Some t where
Some :: Singleton t => t i -> Some t
data Dyn rep where
Dyn :: Singleton t => t i -> i -> Dyn t
data Shape rep where
Nullary :: Int -> Shape rep
Nary :: Int -> [Shape rep] -> Shape rep
Esc :: (Singleton rep, Ord t) => rep t -> t -> Shape rep
instance Ord (Shape rep) where
compare :: Shape rep -> Shape rep -> Ordering
compare (Nullary Int
i) (Nullary Int
j) = forall a. Ord a => a -> a -> Ordering
compare Int
i Int
j
compare (Nullary Int
_) Shape rep
_ = Ordering
LT
compare Shape rep
_ (Nullary Int
_) = Ordering
GT
compare (Nary Int
n [Shape rep]
xs) (Nary Int
m [Shape rep]
ys) = forall a. Ord a => a -> a -> Ordering
compare (Int
n, [Shape rep]
xs) (Int
m, [Shape rep]
ys)
compare (Nary Int
_ [Shape rep]
_) Shape rep
_ = Ordering
LT
compare Shape rep
_ (Nary Int
_ [Shape rep]
_) = Ordering
GT
compare (Esc rep t
r1 t
t1) (Esc rep t
r2 t
t2) =
case forall {k} (t :: k -> *) (i :: k) (j :: k).
Singleton t =>
t i -> t j -> Maybe (i :~: j)
testEql rep t
r1 rep t
r2 of
Just t :~: t
Refl -> forall a. Ord a => a -> a -> Ordering
compare t
t1 t
t2
Maybe (t :~: t)
Nothing -> forall {k} (t :: k -> *) (a :: k) (b :: k).
Singleton t =>
t a -> t b -> Ordering
cmpIndex rep t
r1 rep t
r2
instance Eq (Shape rep) where
Shape rep
a == :: Shape rep -> Shape rep -> Bool
== Shape rep
b = forall a. Ord a => a -> a -> Ordering
compare Shape rep
a Shape rep
b forall a. Eq a => a -> a -> Bool
== Ordering
EQ
instance Ord (Some r) where
compare :: Some r -> Some r -> Ordering
compare (Some r i
x) (Some r i
y) = forall {k} (t :: k -> *) (a :: k) (b :: k).
Singleton t =>
t a -> t b -> Ordering
cmpIndex r i
x r i
y
instance Eq (Some r) where
(Some r i
x) == :: Some r -> Some r -> Bool
== (Some r i
y) = forall {k} (t :: k -> *) (a :: k) (b :: k).
Singleton t =>
t a -> t b -> Ordering
cmpIndex r i
x r i
y forall a. Eq a => a -> a -> Bool
== Ordering
EQ
compareTypeRep :: TypeRep a -> TypeRep b -> Ordering
compareTypeRep :: forall {k} {k} (a :: k) (b :: k).
TypeRep a -> TypeRep b -> Ordering
compareTypeRep (Con TyCon
x) (Con TyCon
y) = forall a. Ord a => a -> a -> Ordering
compare TyCon
x TyCon
y
compareTypeRep (Con TyCon
_) TypeRep b
_ = Ordering
LT
compareTypeRep TypeRep a
_ (Con TyCon
_) = Ordering
GT
compareTypeRep (App TypeRep a
x TypeRep b
a) (App TypeRep a
y TypeRep b
b) =
case forall {k} {k} (a :: k) (b :: k).
TypeRep a -> TypeRep b -> Ordering
compareTypeRep TypeRep a
x TypeRep a
y of
Ordering
EQ -> forall {k} {k} (a :: k) (b :: k).
TypeRep a -> TypeRep b -> Ordering
compareTypeRep TypeRep b
a TypeRep b
b
Ordering
other -> Ordering
other
#if __GLASGOW_HASKELL__ < 906
compareTypeRep (App TypeRep a
_ TypeRep b
_) TypeRep b
_ = Ordering
LT
compareTypeRep TypeRep a
_ (App TypeRep a
_ TypeRep b
_) = Ordering
GT
compareTypeRep (Fun TypeRep arg
x TypeRep res
a) (Fun TypeRep arg
y TypeRep res
b) =
case forall {k} {k} (a :: k) (b :: k).
TypeRep a -> TypeRep b -> Ordering
compareTypeRep TypeRep arg
x TypeRep arg
y of
Ordering
EQ -> forall {k} {k} (a :: k) (b :: k).
TypeRep a -> TypeRep b -> Ordering
compareTypeRep TypeRep res
a TypeRep res
b
Ordering
other -> Ordering
other
#endif
instance Singleton TypeRep where
testEql :: forall (i :: k) (j :: k). TypeRep i -> TypeRep j -> Maybe (i :~: j)
testEql = forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality
cmpIndex :: forall (a :: k) (b :: k). TypeRep a -> TypeRep b -> Ordering
cmpIndex = forall {k} {k} (a :: k) (b :: k).
TypeRep a -> TypeRep b -> Ordering
compareTypeRep
data R t where
IntR :: R Int
BoolR :: R Bool
instance Shaped R any where
shape :: forall i. R i -> Shape any
shape R i
IntR = forall (rep :: * -> *). Int -> Shape rep
Nullary Int
0
shape R i
BoolR = forall (rep :: * -> *). Int -> Shape rep
Nullary Int
1
instance Singleton R where
testEql :: forall i j. R i -> R j -> Maybe (i :~: j)
testEql R i
IntR R j
IntR = forall a. a -> Maybe a
Just forall {k} (a :: k). a :~: a
Refl
testEql R i
BoolR R j
BoolR = forall a. a -> Maybe a
Just forall {k} (a :: k). a :~: a
Refl
testEql R i
_ R j
_ = forall a. Maybe a
Nothing
cmpIndex :: forall a b. R a -> R b -> Ordering
cmpIndex R a
x R b
y = forall a. Ord a => a -> a -> Ordering
compare @(Shape TypeRep) (forall {k} (t :: k -> *) (rep :: * -> *) (i :: k).
Shaped t rep =>
t i -> Shape rep
shape @R R a
x) (forall {k} (t :: k -> *) (rep :: * -> *) (i :: k).
Shaped t rep =>
t i -> Shape rep
shape @R R b
y)