1 {-# LANGUAGE DataKinds #-}
3 {-# LANGUAGE PolyKinds #-}
4 {-# LANGUAGE Rank2Types #-}
5 {-# LANGUAGE TypeFamilies #-}
6 {-# LANGUAGE TypeOperators #-}
7 module Language.Symantic.Typing.Kind where
10 import Data.Type.Equality
11 import GHC.Prim (Constraint)
17 | KiCon -- ^ 'Constraint'
18 | (:>) Kind Kind -- ^ \->
21 -- * Type family 'Kind_of'
22 -- | To be completed on need, according to the /type constants/ used.
23 type family Kind_of (x::k) :: Kind
24 type instance Kind_of (x:: Constraint) = 'KiCon
25 type instance Kind_of (x:: * -> Constraint) = 'KiTerm ':> 'KiCon
26 type instance Kind_of (x:: *) = 'KiTerm
27 type instance Kind_of (x:: * -> *) = 'KiTerm ':> 'KiTerm
28 type instance Kind_of (x:: (* -> *) -> *) = ('KiTerm ':> 'KiTerm) ':> 'KiTerm
29 type instance Kind_of (x:: (* -> *) -> Constraint) = ('KiTerm ':> 'KiTerm) ':> 'KiCon
30 type instance Kind_of (x:: * -> * -> *) = 'KiTerm ':> 'KiTerm ':> 'KiTerm
32 -- ** Type family 'Kind_of_Proxy'
33 type family Kind_of_Proxy (x:: *) :: Kind where
34 Kind_of_Proxy (Proxy x) = Kind_of x
35 -- | Convenient shorter type synonym.
36 type Ki h = Kind_of_Proxy h
39 -- | Existential for 'Kind'.
40 data EKind = forall k. EKind (SKind k)
41 instance Eq EKind where
43 | Just _ <- testEquality x y = True
45 instance Show EKind where
46 show (EKind x) = show x
49 -- | Singleton for 'Kind'.
50 data SKind (k::Kind) where
51 SKiTerm :: SKind 'KiTerm
52 SKiCon :: SKind 'KiCon
53 SKiArrow :: SKind a -> SKind b -> SKind (a ':> b)
54 instance TestEquality SKind where
55 testEquality SKiTerm SKiTerm = Just Refl
56 testEquality SKiCon SKiCon = Just Refl
57 testEquality (SKiArrow xa xb) (SKiArrow ya yb)
58 | Just Refl <- testEquality xa ya
59 , Just Refl <- testEquality xb yb
61 testEquality _ _ = Nothing
62 instance Show (SKind k) where
64 show SKiCon = "Constraint"
65 show (SKiArrow a b) = "(" ++ show a ++ " -> " ++ show b ++ ")"
68 -- | Implicit for 'Kind'.
69 class IKind (k::Kind) where
71 instance IKind 'KiTerm where
73 instance IKind 'KiCon where
75 instance (IKind a, IKind b) => IKind (a ':> b) where
76 kind = kind `SKiArrow` kind