1 {-# LANGUAGE DataKinds #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE FlexibleInstances #-}
5 {-# LANGUAGE MultiParamTypeClasses #-}
6 {-# LANGUAGE PolyKinds #-}
7 {-# LANGUAGE Rank2Types #-}
8 {-# LANGUAGE ScopedTypeVariables #-}
9 {-# LANGUAGE StandaloneDeriving #-}
10 {-# LANGUAGE TypeFamilies #-}
11 {-# LANGUAGE TypeOperators #-}
12 {-# LANGUAGE TypeInType #-}
13 {-# LANGUAGE UndecidableInstances #-}
14 module Language.Symantic.Typing.Type where
16 import Data.Monoid ((<>))
18 import Data.Maybe (fromMaybe, isJust)
19 import Data.Type.Equality
20 import qualified Data.Kind as K
22 import Language.Symantic.Typing.Kind
23 import Language.Symantic.Typing.Constant
24 import Language.Symantic.Typing.Syntax
30 -- * @cs@: /type constants/, fixed at compile time.
31 -- * @h@: indexed Haskell type.
33 -- * 'TyConst': /type constant/, selected amongst @cs@.
34 -- * @(:$)@: /type application/.
35 data Type (cs::[K.Type]) (h::k) where
50 instance TestEquality (Type cs) where
51 testEquality = eq_type
52 instance Eq (Type cs h) where
54 instance Show_Const cs => Show (Type cs h) where
56 -- deriving instance Show_Const cs => Show (Type cs h)
58 kind_of :: Type cs (h::k) -> SKind k
61 TyConst c -> kind_of_const c
64 _kx `SKiArrow` kf -> kf
67 :: Type cs (x::k) -> Type cs (y::k) -> Maybe (x:~:y)
68 eq_type (TyConst x) (TyConst y)
69 | Just Refl <- testEquality x y
71 eq_type (xf :$ xx) (yf :$ yx)
72 | Just Refl <- eq_skind (kind_of xf) (kind_of yf)
73 , Just Refl <- eq_type xf yf
74 , Just Refl <- eq_type xx yx
79 :: Type cs (x::kx) -> Type cs (y::ky) -> Maybe (kx:~:ky)
80 eq_kind_type (TyConst x) (TyConst y)
81 | Just Refl <- eq_kind_const x y
83 eq_kind_type (xf :$ xx) (yf :$ yx)
84 | Just Refl <- eq_kind_type xf yf
85 , Just Refl <- eq_kind_type xx yx
87 eq_kind_type _x _y = Nothing
89 show_type :: Show_Const cs => Type cs h -> String
90 show_type (TyConst c) = show c
91 show_type ((:$) f@(:$){} a@(:$){}) = "(" <> show_type f <> ") (" <> show_type a <> ")"
92 show_type ((:$) f@(:$){} a) = "(" <> show_type f <> ") " <> show_type a
93 show_type ((:$) f a@(:$){}) = show_type f <> " (" <> show_type a <> ")"
94 show_type ((:$) f a) = show_type f <> " " <> show_type a
95 -- show_type (TyVar v) = "t" <> show (integral_from_peano v::Integer)
98 -- | Existential for 'Type'.
99 data EType cs = forall h. EType (Type cs h)
101 instance Eq (EType cs) where
103 | Just Refl <- eq_kind_type x y
104 = isJust $ eq_type x y
106 instance Show_Const cs => Show (EType cs) where
107 show (EType ty) = show ty
110 -- | Existential for 'Type' of a known 'Kind'.
111 data KType cs k = forall (h::k). KType (Type cs h)
113 instance Eq (KType cs ki) where
114 KType x == KType y = isJust $ eq_type x y
115 instance Show_Const cs => Show (KType cs ki) where
116 show (KType ty) = show_type ty
118 -- * Class 'Type_from'
119 -- | Try to build a 'Type' from raw data.
120 class Type_from ast cs where
123 -> (forall k h. Type cs (h::k) -> Either (Error_Type cs ast) ret)
124 -> Either (Error_Type cs ast) ret
126 -- ** Type 'Error_Type'
127 data Error_Type cs ast
128 = Error_Type_Constant_unknown (At ast (Lexem ast))
129 | Error_Type_Kind_mismatch (At ast EKind) (At ast EKind)
130 | Error_Type_Kind_not_applicable (At ast EKind)
131 deriving instance (Eq ast, Eq (Lexem ast)) => Eq (Error_Type cs ast)
132 deriving instance (Show ast, Show (Lexem ast), Show_Const cs) => Show (Error_Type cs ast)
135 ( Const_from (Lexem ast) cs
137 ) => Type_from ast cs where
139 fromMaybe (Left $ Error_Type_Constant_unknown $ At (Just ast) $ ast_lexem ast) $
140 const_from (ast_lexem ast) $ \c -> Just $
141 go (ast_nodes ast) (TyConst c) kk
145 -> (forall k' h'. Type cs (h'::k') -> Either (Error_Type cs ast) ret)
146 -> Either (Error_Type cs ast) ret
148 go (ast_x:ast_xs) ty_f k =
149 type_from ast_x $ \ty_x ->
151 ki_f_a `SKiArrow` _ki_f_b ->
152 let ki_x = kind_of ty_x in
153 case eq_skind ki_f_a ki_x of
154 Just Refl -> go ast_xs (ty_f :$ ty_x) k
155 Nothing -> Left $ Error_Type_Kind_mismatch
156 (At (Just ast) $ EKind ki_f_a)
157 (At (Just ast_x) $ EKind ki_x)
158 ki -> Left $ Error_Type_Kind_not_applicable $ At (Just ast) $ EKind ki
161 data Args (cs::[K.Type]) (args::[K.Type]) where
165 -> Args cs (Proxy arg ': args)
168 -- | Build the left spine of a 'Type'.
171 -> (forall kc (c::kc) as. Const cs c -> Args cs as -> ret) -> ret
172 spine_of_type (TyConst c) k = k c ArgZ
173 spine_of_type (f :$ a) k = spine_of_type f $ \c as -> k c (a `ArgS` as)
178 tyUnit :: Inj_Const cs () => Type cs ()
179 tyUnit = TyConst inj_const