1 {-# LANGUAGE ConstraintKinds #-}
3 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
4 {-# LANGUAGE TypeInType #-}
5 {-# LANGUAGE UndecidableInstances #-}
6 {-# LANGUAGE ViewPatterns #-}
7 {-# OPTIONS_GHC -fno-warn-orphans #-}
8 module Language.Symantic.Typing.Type where
10 import Control.Applicative (Applicative(..))
11 import qualified Data.Char as Char
12 import Data.Monoid ((<>))
14 import Data.Maybe (fromMaybe, isJust)
15 import Data.String (IsString(..))
16 import Data.Text (Text)
17 import qualified Data.List as List
18 import qualified Data.Text as Text
19 import Data.Type.Equality
20 import qualified Data.Kind as K
21 import GHC.Exts (Constraint)
22 import Data.Void (Void)
23 import Unsafe.Coerce (unsafeCoerce)
26 import Language.Symantic.Typing.Kind
27 import Language.Symantic.Typing.Constant
28 import Language.Symantic.Parsing
34 -- * @vs@: /type variables/, fixed at compile time.
35 -- * @cs@: /type constants/, fixed at compile time.
36 -- * @h@: indexed Haskell type.
37 -- * @k@: indexed Haskell kind of @h@.
39 -- * 'TyConst': /type constant/, selected amongst @cs@.
40 -- * 'TyVar': /type variable/.
41 -- Note that only the kind @k@ is coerced,
42 -- @h@ being set to 'Any' to loose the type indexing.
43 -- Note also that there is no De Bruijn encoding done to link 'TyPi's and 'TyVar's.
44 -- * 'TyPi': /type abstraction/.
45 -- Note that only the kind @k@ is coerced,
46 -- @h@ being set to 'Any' to loose the type indexing.
47 -- * @(:$)@: /type application/.
48 -- * @(:=>)@: /type constraint/.
49 -- Note that there is no proof of the 'Constraint' attached.
51 -- See also: https://ghc.haskell.org/trac/ghc/wiki/Typeable
52 -- Which currently concludes:
53 -- "Why kind equalities, then? Given the fact that Richard's branch
54 -- doesn't solve this problem, what is it good for?
55 -- It still works wonders in the mono-kinded case,
56 -- such as for decomposing ->.
57 -- It's just that poly-kinded constructors are still a pain."
59 data Type (cs::[K.Type]) (h::k) where
60 TyConst :: TyConst cs c -> Type cs c
61 (:$) :: Type cs f -> Type cs x -> Type cs (f x)
62 TyVar :: SKind k -> Var -> Type cs (Any::k)
63 TyPi :: SKind kv -> (forall (v::kv). Type cs v -> Type cs (Any::k)) -> Type cs (Any::k)
64 (:=>) :: {-c =>-} Type cs (c::Constraint) -> Type cs h -> Type cs h
68 -- | /beta-reduction/: when possible, substitute
69 -- the abstraction of a 'TyPi' with a given 'Type'.
70 tyApp :: Type cs a -> Type cs b -> Maybe (Type cs a)
72 | Just Refl <- eq_SKind kv (kind_of v)
80 -- | Drop the type index.
82 -- Useful when the type index cannot represent the wanted type,
83 -- like a polymorphic type.
84 tyVoid :: Type cs (a::k) -> Type cs (Any::Void)
86 kindVoid :: SKind k -> SKind Void
87 kindVoid = unsafeCoerce
88 reflVoid :: (x::Void) :~: (y::Void)
89 reflVoid = unsafeCoerce Refl
91 -- | 'Type' constructor to be used
92 -- with @TypeApplications@
93 -- and @NoMonomorphismRestriction@.
94 ty :: forall c cs. Inj_TyConst cs c => Type cs c
95 ty = TyConst inj_TyConst
96 -- NOTE: The forall brings @c@ first in the type variables,
97 -- which is convenient to use @TypeApplications@.
99 kind_of :: Type cs (h::k) -> SKind k
102 TyConst c -> kind_of_TyConst c
105 _kx `SKiArrow` kf -> kf
106 _c :=> x -> kind_of x
108 TyPi k f -> kind_of $ f (TyVar k 0)
110 -- | Return the smallest 'Var' not used in given 'Type'.
111 freeTyVar :: Type cs (h::k) -> Var
112 freeTyVar = (+ 1) . maxTyVar (-1)
114 maxTyVar :: Var -> Type cs h -> Var
115 maxTyVar m TyConst{} = m
116 maxTyVar m (f :$ a) = maxTyVar m f `max` maxTyVar m a
117 maxTyVar m (TyVar _kv v) = max m v
118 maxTyVar m (TyPi kv f) = maxTyVar m $ f $ TyVar kv (-1)
119 maxTyVar m (_c :=> x) = maxTyVar m x
121 -- | Return the 'Var's (without doubles) used in given 'Type'.
122 freeTyVars :: Type cs (h::k) -> [Var]
123 freeTyVars = List.nub . go
125 go :: Type cs h -> [Var]
127 go (f :$ a) = go f `List.union` go a
128 go (TyVar _kv v) | v >= 0 = [v]
130 go (TyPi kv f) = go $ f $ TyVar kv (-1)
133 eq_Type :: Type cs (x::k)
142 eq _v (TyConst x) (TyConst y)
143 | Just Refl <- testEquality x y
145 eq v (xf :$ xx) (yf :$ yx)
146 | Just Refl <- eq_SKind (kind_of xf) (kind_of yf)
147 , Just Refl <- eq v xf yf
148 , Just Refl <- eq v xx yx
150 eq v (TyPi xk x::Type cs xv) (TyPi xy y::Type cs yv)
151 | Just Refl <- eq_SKind xk xy
152 , Just Refl <- eq (v - 1) (x $ TyVar xk v) (y $ TyVar xy v)
154 eq _v (TyVar xk x) (TyVar yk y)
155 | Just Refl <- eq_SKind xk yk
158 eq v (xc :=> x) (yc :=> y)
159 | Just Refl <- eq v xc yc
160 , Just Refl <- eq v x y
164 eq_Kind_Type :: Type cs (x::kx)
169 eq :: Type cs (x::kx)
172 eq (TyConst x) (TyConst y)
173 | Just Refl <- eq_Kind_TyConst x y
175 eq (xf :$ xx) (yf :$ yx)
176 | Just Refl <- eq xf yf
177 , Just Refl <- eq xx yx
179 eq (TyPi xk x::Type cs xv) (TyPi xy y::Type cs yv)
180 | Just Refl <- eq_SKind xk xy
181 , Just Refl <- eq (x $ TyVar xk 0) (y $ TyVar xy 0)
183 eq (TyVar kx _x) (TyVar ky _y)
184 | Just Refl <- eq_SKind kx ky
186 eq (_xc :=> x) (_yc :=> y)
187 | Just Refl <- eq x y
191 show_Type :: Show_TyConst cs => Int -> Type cs h -> ShowS
192 show_Type pr t = go (freeTyVar t) pr t
194 go :: Show_TyConst cs => Var -> Int -> Type cs h -> ShowS
195 go _v p (TyConst c) = showsPrec p c
196 go _v p (TyVar _kv v) = showString "a" . showsPrec p v
208 let var = TyVar kv v in
210 showString "forall " .
215 instance TestEquality (Type cs) where
216 testEquality = eq_Type
217 instance Eq (Type cs h) where
219 instance Show_TyConst cs => Show (Type cs h) where
220 showsPrec = show_Type
223 -- | Existential for 'Type'.
224 data EType cs = forall h. EType (Type cs h)
226 instance Eq (EType cs) where
228 | Just Refl <- eq_Kind_Type x y
229 = isJust $ eq_Type x y
231 instance Show_TyConst cs => Show (EType cs) where
232 show (EType t) = show t
235 -- | Existential for 'Type' of a known 'Kind'.
236 data KType cs k = forall (h::k). KType (Type cs h)
238 instance Eq (KType cs ki) where
239 KType x == KType y = isJust $ eq_Type x y
240 instance Show_TyConst cs => Show (KType cs ki) where
241 showsPrec p (KType t) = show_Type p t
244 newtype TyName = TyName Text
245 deriving (Eq, Ord, Show)
246 instance IsString TyName where
247 fromString = TyName . fromString
249 -- * Class 'Read_TyName'
250 type Read_TyName raw cs = Read_TyNameR raw cs cs
253 :: forall raw cs ret.
254 Read_TyNameR raw cs cs
255 => raw -> (forall k c. Type cs (c::k) -> Maybe ret)
257 read_TyName = read_TyNameR (Proxy @cs)
259 -- ** Class 'Read_TyNameR'
260 class Read_TyNameR raw cs rs where
262 :: Proxy rs -> raw -> (forall k c. Type cs (c::k) -> Maybe ret)
265 instance Read_TyNameR raw cs '[] where
266 read_TyNameR _cs _c _k = Nothing
268 -- TODO: move each of these to a dedicated module.
270 ( Read_TyNameR TyName cs rs
271 , Inj_TyConst cs Fractional
272 ) => Read_TyNameR TyName cs (Proxy Fractional ': rs) where
273 read_TyNameR _cs (TyName "Fractional") k = k (ty @Fractional)
274 read_TyNameR _rs raw k = read_TyNameR (Proxy @rs) raw k
276 ( Read_TyNameR TyName cs rs
278 , Inj_TyConst cs Char
279 ) => Read_TyNameR TyName cs (Proxy String ': rs) where
280 read_TyNameR _cs (TyName "String") k = k (ty @[] :$ ty @Char)
281 read_TyNameR _rs raw k = read_TyNameR (Proxy @rs) raw k
283 -- * Type 'Token_Type'
284 type Token_Type = Type '[] ()
287 data instance TokenT meta ts (Proxy Token_Type)
288 = Token_Type TyName [EToken meta ts]
289 deriving instance Eq_Token meta ts => Eq (TokenT meta ts (Proxy Token_Type))
290 deriving instance Show_Token meta ts => Show (TokenT meta ts (Proxy Token_Type))
292 ( Read_TyNameR TyName cs rs
293 , Inj_TyConst cs Token_Type
294 ) => Read_TyNameR TyName cs (Proxy Token_Type ': rs) where
295 read_TyNameR _rs (TyName "Type") k = k (ty @Token_Type)
296 read_TyNameR _rs raw k = read_TyNameR (Proxy @rs) raw k
297 instance Show_TyConst cs => Show_TyConst (Proxy Token_Type ': cs) where
298 show_TyConst TyConstZ{} = "Type"
299 show_TyConst (TyConstS c) = show_TyConst c
301 -- * Type 'Error_Type'
302 data Error_Type meta ts
303 = Error_Type_Token_invalid (EToken meta ts)
304 | Error_Type_Constant_unknown (At meta ts TyName)
305 | Error_Type_Con_Kind (Con_Kind meta ts)
306 deriving instance (Eq_TokenR meta ts ts) => Eq (Error_Type meta ts)
307 deriving instance (Show_TokenR meta ts ts) => Show (Error_Type meta ts)
309 -- * Class 'MonoLift'
310 class MonoLift a b where
314 (Error_Type meta ts) where
317 MonoLift (Con_Kind meta ts) (Error_Type meta ts) where
318 olift = olift . Error_Type_Con_Kind
321 data Con_Kind meta ts
322 = Con_Kind_Eq (At meta ts EKind) (At meta ts EKind)
323 | Con_Kind_Arrow (At meta ts EKind)
324 deriving instance (Eq_TokenR meta ts ts) => Eq (Con_Kind meta ts)
325 deriving instance (Show_TokenR meta ts ts) => Show (Con_Kind meta ts)
328 :: MonoLift (Con_Kind meta ts) err
329 => At meta ts (SKind x)
330 -> At meta ts (SKind y)
331 -> ((x :~: y) -> Either err ret) -> Either err ret
333 case unAt x `eq_SKind` unAt y of
335 Nothing -> Left $ olift $
336 Con_Kind_Eq (EKind <$> x) (EKind <$> y)
339 :: MonoLift (Con_Kind meta ts) err
340 => At meta ts (SKind x)
341 -> (forall a b. (x :~: (a -> b)) -> SKind a -> SKind b -> Either err ret)
343 check_Kind_Arrow x k =
345 a `SKiArrow` b -> k Refl a b
347 Con_Kind_Arrow (EKind <$> x)
349 -- * Class 'Compile_Type'
351 -- | Try to build a 'Type' from an 'EToken'.
352 class Compile_Type ts cs where
354 :: ( MonoLift (Error_Type meta ts) err
355 , MonoLift (Con_Kind meta ts) err )
357 -> (forall k h. Type cs (h::k) -> Either err ret)
361 ( Read_TyName TyName cs
362 , Proj_Token ts Token_Type
363 ) => Compile_Type ts cs where
365 :: forall meta err ret.
366 ( MonoLift (Error_Type meta ts) err
367 , MonoLift (Con_Kind meta ts) err
369 -> (forall k h. Type cs (h::k) -> Either err ret)
371 compile_Type tok@(proj_EToken -> Just (Token_Type cst args)) kk =
372 fromMaybe (Left $ olift $ Error_Type_Constant_unknown $ At (Just tok) cst) $
373 read_TyName cst $ \typ -> Just $
376 go :: [EToken meta ts]
378 -> (forall k' h'. Type cs (h'::k') -> Either err ret)
381 go (tok_x:tok_xs) ty_f k =
382 compile_Type tok_x $ \(ty_x::Type cs (h'::k')) ->
384 (At (Just tok) $ kind_of ty_f) $ \Refl ki_f_a _ki_f_b ->
386 (At (Just tok) ki_f_a)
387 (At (Just tok_x) $ kind_of ty_x) $ \Refl ->
388 go tok_xs (ty_f :$ ty_x) k
389 compile_Type tok _k = Left $ olift $ Error_Type_Token_invalid tok
392 :: Read_TyName TyName cs
393 => EToken meta '[Proxy Token_Type]
394 -> Either (Error_Type meta '[Proxy Token_Type]) (EType cs)
395 compile_EType tok = compile_Type tok (Right . EType)
398 data Types cs (hs::[K.Type]) where
399 TypesZ :: Types cs '[]
402 -> Types cs (Proxy h ': hs)
405 eTypes :: Types cs hs -> [EType cs]
407 eTypes (TypesS t ts) = EType t : eTypes ts
409 -- | Build the left spine of a 'Type'.
412 -> (forall ka (a::ka) hs.
413 Either Var (TyConst cs a) -> Types cs hs -> ret)
418 -> (forall ka (a::ka) hs.
419 Either Var (TyConst cs a) -> Types cs hs -> ret)
421 go (TyConst c) k = k (Right c) TypesZ
422 go (f :$ a) k = go f $ \c as -> k c (a `TypesS` as)
423 go (TyVar _kv v) k = k (Left v) TypesZ
424 go (TyPi _kv _f) _k = undefined -- FIXME: see what to do in this case.
425 go (_c :=> x) k = go x k
428 type family UnProxy (x::K.Type) :: k where
429 UnProxy (Proxy x) = x
431 -- * Class 'Gram_Type'
432 type TokType meta = EToken meta '[Proxy Token_Type]
444 ) => Gram_Type meta g where
445 g_type :: CF g (TokType meta)
446 g_type = rule "type" $ g_type_fun
447 g_type_fun :: CF g (TokType meta)
448 g_type_fun = rule "type_fun" $
449 infixrG g_type_list (metaG $ op <$ symbol "->")
450 where op meta a b = inj_EToken meta $ Token_Type "(->)" [a, b]
451 g_type_list :: CF g (TokType meta)
452 g_type_list = rule "type_list" $
454 (symbol "[") (option [] (pure <$> g_type)) (symbol "]")
455 (const <$> g_type_tuple2)
456 where f a meta = inj_EToken meta $ Token_Type "[]" a
457 g_type_tuple2 :: CF g (TokType meta)
458 g_type_tuple2 = rule "type_tuple2" $
459 try (parens (infixrG g_type (metaG $ op <$ symbol ","))) <+> g_type_app
460 where op meta a b = inj_EToken meta $ Token_Type "(,)" [a, b]
461 g_type_app :: CF g (TokType meta)
462 g_type_app = rule "type_app" $
463 f <$> some g_type_atom
465 f :: [TokType meta] -> TokType meta
466 f (EToken (TokenZ meta (Token_Type a as)):as') =
467 EToken $ TokenZ meta $ Token_Type a $ as <> as'
468 f _ = error "Oops, the impossible happened"
469 g_type_atom :: CF g (TokType meta)
470 g_type_atom = rule "type_atom" $
471 try (parens g_type) <+>
474 g_type_name :: CF g (TokType meta)
475 g_type_name = rule "type_name" $
477 (\c cs meta -> EToken $ TokenZ meta $ Token_Type (TyName $ Text.pack $ c:cs) [])
478 <$> unicat (Unicat Char.UppercaseLetter)
479 <*> many (choice $ unicat <$> [Unicat_Letter, Unicat_Number])
480 g_type_symbol :: CF g (TokType meta)
481 g_type_symbol = rule "type_symbol" $
483 parens $ many $ cf_of_Terminal $ choice g_ok `but` choice g_ko
485 f s meta = inj_EToken meta $ (`Token_Type` []) $
486 TyName $ Text.concat ["(", Text.pack s, ")"]
492 g_ko = char <$> ['(', ')', '`']
494 deriving instance Gram_Type meta g => Gram_Type meta (CF g)
495 instance Gram_Type meta EBNF
496 instance Gram_Type meta RuleDef
498 -- | List of the rules of 'Gram_Type'.
499 gram_type :: Gram_Type meta g => [CF g (TokType meta)]