1 {-# LANGUAGE ConstraintKinds #-}
3 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
4 {-# LANGUAGE TypeInType #-}
5 {-# LANGUAGE UndecidableInstances #-}
6 {-# OPTIONS_GHC -fno-warn-orphans #-}
7 module Language.Symantic.Typing.Type
8 ( module Language.Symantic.Typing.Type
14 import Data.Map.Strict (Map)
15 import Data.Maybe (isJust)
17 import Data.Semigroup ((<>))
19 import Data.Text (Text)
20 import Data.Type.Equality
21 import GHC.Exts (Constraint)
23 -- import Data.Typeable (Typeable, eqT)
24 import qualified Data.Kind as K
25 import qualified Data.List as List
26 import qualified Data.Map.Strict as Map
27 import qualified Data.Set as Set
28 import qualified Data.Text as Text
30 import Language.Symantic.Grammar
31 import Language.Symantic.Typing.Kind
32 import Language.Symantic.Typing.Constant
33 import Language.Symantic.Parsing
35 -- * Type 'T', for both 'Type' and 'Term'
37 -- | /Type of terms/ embedding… /terms/ to be able
38 -- to have /polymorphic terms/ (ie. handle quantified variables).
41 -- * @cs@: /type constants/, fixed at compile time.
42 -- * @h@: indexed Haskell type.
43 -- * @k@: indexed Haskell kind of @h@.
45 -- * 'TyConst': /type constant/, selected amongst @cs@.
47 -- * 'TyApp': /type parameter application/.
49 -- * 'TyQuant': /type universal quantification/ (aka. /type abstraction/):
50 -- used to introduce (and bind) a /type variable/.
52 -- Note that the type indexing is lost (though not kind @k@),
53 -- because GHC cannot represent a quantified type in a type
54 -- aka. impredicative polymorphism.
56 -- * 'TyVar': /type variable/:,
57 -- used to represent a /bounded type variable/,
58 -- when passing through a 'TyQuant'.
60 -- Note that only the kind @k@ is flexible,
61 -- @h@ being set to 'Any' to loose the type indexing
62 -- and enabling the return of a type equality when the 'Var's are the same.
64 -- Note also that there is no DeBruijn encoding done to link 'TyQuant's and 'TyVar's.
66 -- * 'Term': /term/, useful to embed a term
67 -- requiring quantifications and qualifications.
69 -- See also: https://ghc.haskell.org/trac/ghc/wiki/Typeable
70 -- Which currently concludes:
71 -- "Why kind equalities, then? Given the fact that Richard's branch
72 -- doesn't solve this problem, what is it good for?
73 -- It still works wonders in the mono-kinded case,
74 -- such as for decomposing ->.
75 -- It's just that poly-kinded constructors are still a pain."
76 data T (src::K.Type) (cs::[K.Type]) (h::k) where
77 TyConst :: src -> TyConst src cs c
79 TyApp :: src -> Type src cs f
82 -- NOTE: @f a@ decomposition made possible
83 -- at the cost of requiring @TypeInType@.
84 TyQuant :: src -> NameHint
86 -> (forall (v::kv). Type src cs v -> KType src cs k)
88 TyVar :: src -> Kind src kv
90 -> Type src cs (Any::kv)
99 type Term src cs h = T src cs (h::K.Type)
101 -- | Remove all top 'Term's.
102 unTerm :: Type src cs (h::k) -> Type src cs (h::k)
103 unTerm (Term _te x) = unTerm x
106 -- | 'Type' constructor to be used with @TypeApplications@ and @NoMonomorphismRestriction@.
107 ty :: forall c src cs. (Source src, Inj_TyConst cs c) => Type src cs c
108 ty = TyConst sourceLess inj_TyConst
109 -- NOTE: The forall brings @c@ first in the type variables,
110 -- which is convenient to use @TypeApplications@.
112 (~>) :: Source src => Inj_TyConst cs (->)
113 => Type src cs a -> Type src cs b -> Type src cs (a -> b)
114 (~>) a b = (ty @(->) `tyApp` a) `tyApp` b
117 -- | Like 'ty', but for a known 'Source'.
118 tySourced :: forall c src cs. (Source src, Inj_TyConst cs c) => src -> Type src cs c
119 tySourced src = TyConst src inj_TyConst
121 -- | Like 'TyApp', but 'sourceLess'.
122 tyApp :: Source src => Type src cs f -> Type src cs a -> Type src cs (f a)
123 tyApp = TyApp sourceLess
126 -- | Like 'TyQuant', but 'sourceLess'.
131 -> (forall (v::kv). Type src cs v -> KT src cs k)
133 tyQuant n kv f = KT $ TyQuant sourceLess n kv f
135 -- | Return the 'Kind' of the given 'Type'.
136 kindTy :: Inj_Source (EType src cs) src => Type src cs (h::k) -> Kind src k
137 kindTy t = kindTyOS t `source` EType t
139 -- | Like 'kindTy' but keep the old 'Source'.
140 kindTyOS :: Type src cs (h::k) -> Kind src k
143 go :: forall cs src k h. Type src cs (h::k) -> Kind src k
145 TyConst _src c -> kindTyConst c
148 KiArrow _src_kf _kx kf -> kf
149 TyQuant src _n k f -> unKT kindTyOS $ f (TyVar src k 0)
151 Term _te x -> kindTyOS x
153 instance -- TestEquality
154 Inj_Source (EType src cs) src
155 => TestEquality (Type src cs) where
157 instance Eq (Type src cs h) where
160 -- | Return a proof when two 'Type's are equals.
162 -- NOTE: 'TyQuant's are not compared:
163 -- they first have to be monomorphized.
164 eqTy :: Type src cs (x::k) -> Type src cs (y::k) -> Maybe (x:~:y)
167 go :: Type src cs (x::k) -> Type src cs (y::k) -> Maybe (x:~:y)
168 go (TyConst _sx x) (TyConst _sy y)
169 | Just Refl <- testEquality x y
171 go (TyApp _sx fx xx) (TyApp _sy fy xy)
172 | Just Refl <- eqKi (kindTyOS fx) (kindTyOS fy)
173 , Just Refl <- go fx fy
174 , Just Refl <- go xx xy
176 go TyQuant{} TyQuant{} = Nothing
178 go v (TyQuant sx _nx kx x::Type src cs vx)
179 (TyQuant sy _ny ky y::Type src cs vy)
180 | Just Refl <- eqKi kx ky
181 , Just Refl <- go (v - 1) (x $ TyVar sx kx v) (y $ TyVar sy ky v)
184 go (TyVar _sx kx x) (TyVar _sy ky y)
185 | Just Refl <- eqKi kx ky
188 -- NOTE: 'Term' are transparent to 'eqTy'.
189 go (Term _tx x) (Term _ty y) | Just Refl <- go x y = Just Refl
190 go (Term _tx x) y | Just Refl <- go x y = Just Refl
191 go x (Term _ty y) | Just Refl <- go x y = Just Refl
194 -- | Return two proofs when two 'Type's are equals:
195 -- one for the type and one for the kind.
196 eqKiTy :: Type src cs (x::kx) -> Type src cs (y::ky) -> Maybe (x:~~:y)
199 go :: Type src cs (x::kx) -> Type src cs (y::ky) -> Maybe (x:~~:y)
200 go (TyConst _sx x) (TyConst _sy y) = eqKiTyConst x y
201 go (TyApp _sx fx xx) (TyApp _sy fy xy)
202 | Just KRefl <- go fx fy
203 , Just KRefl <- go xx xy
205 go TyQuant{} TyQuant{} = Nothing
206 go (TyVar _sx kx _x) (TyVar _sy ky _y)
207 | Just Refl <- eqKi kx ky
209 go (Term _tx x) (Term _ty y) = go x y
213 -- | 'TyConst' to qualify a 'Type'.
214 data (#>) (q::Constraint) (a::K.Type)
215 instance Fixity_TyConstC (#>) where
216 fixity_TyConstC _ = FixityInfix $ infixR 0
220 => Inj_TyConst cs (#>)
221 => Type src cs a -> Type src cs b -> Type src cs (a #> b)
222 (#>) a b = (ty @(#>) `tyApp` a) `tyApp` b
224 -- NOTE: should actually be (-1)
225 -- to compose well with @infixr 0 (->)@
226 -- but this is not allowed by GHC.
232 ) => Show (Type src cs h) where
235 showTy :: forall cs src h.
238 => Int -> Type src cs h -> ShowS
243 (Map.empty, namesTy typ) typ
246 Maybe (Type src cs p) -- parent Type, used to prettify
247 -> (Infix, LR) -- fixity and associativity
248 -> Var -- variable counter (DeBruijn)
249 -> ( Map Var Name -- names of bound variables
250 , Names -- used names : bound variables', free variables' and constants'
254 go _prev (po, _) _v _vs (TyConst _src c) = showsPrec (precedence po) c
255 go _prev po v vs t@(TyApp _ (TyApp _ (TyConst _ f) a) b)
256 | FixityInfix op <- fixity_TyConst f =
257 showParen (parenInfix po op) $
258 go (Just t) (op, L) v vs a .
260 showString (unParen $ show_TyConst f) .
262 go (Just t) (op, R) v vs b
264 unParen ('(':s) | ')':s' <- reverse s = reverse s'
266 go _prev po v vs t@(TyApp _src f a) =
267 let op = infixR 11 in
268 showParen (parenInfix po op) $
269 go (Just t) (op, L) v vs f .
271 go (Just t) (op, R) v vs a
272 go prev po v (vs, ns) t@(TyQuant src nv kv f) =
274 let var = TyVar src kv v in
275 let n = freshifyName ns nv in
276 let vs' = Map.insert v n vs in
277 let ns' = Set.insert n ns in
280 showParen (parenInfix po op) $
283 _ -> showString "forall") .
285 go Nothing po v (vs', ns') var .
288 _ -> showString ". ") .
289 go (Just t) (op, R) (v + 1) (vs', ns') x
290 go _prev _po _v (vs, _ns) (TyVar _src _kv v) =
291 case Map.lookup v vs of
292 Nothing -> showChar '#' . showsPrec 0 v
293 Just n -> showString $ Text.unpack n
294 go _prev po v vs t@(Term _te x) =
296 go (Just t) po v vs x
298 showBracket :: Bool -> ShowS -> ShowS
299 showBracket b p = if b then showChar '{' . p . showChar '}' else p
302 -- | Captures the proof of a 'Constraint'
303 -- (and its dictionaries when it contains type classes):
304 -- pattern matching on the 'TyCon' constructor
305 -- brings the 'Constraint' into scope.
309 -- ** Type 'TyFamName'
310 type TyFamName = Text
313 class Sym (term::K.Type -> K.Type) where
314 sym_lam :: (term a -> term b) -> term (a -> b)
315 sym_app :: term (a -> b) -> (term a -> term b)
316 sym_int :: Int -> term Int
317 sym_id :: term (a -> a)
318 sym_uc :: term (Char -> Char)
319 -- sym_bind :: Monad m => term (m a) -> term (a -> m b) -> term (m b)
320 -- sym_bind :: term (Monad m #> (m a -> (a -> m b) -> m b))
321 sym_bind :: Monad m => term (m a -> (a -> m b) -> m b)
322 sym_const :: term a -> term b -> term a
323 -- sym_comp :: term (b -> c) -> term (a -> c) -> term (a -> b)
324 sym_comp :: term ((b -> c) -> (a -> b) -> a -> c)
327 data TeSym (h::K.Type) = TeSym (forall term. Sym term => term h)
329 instance Source src => Sourced (Type src cs h) where
330 type Source_of (Type src cs h) = src
332 source_of (TyConst src _c) = src
333 source_of (TyApp src _f _x) = src
334 source_of (TyQuant src _n _kv _f) = src
335 source_of (TyVar src _kv _v) = src
336 source_of (Term _te x) = source_of x
338 source_is (TyConst _src c) src = TyConst src c
339 source_is (TyApp _src f x) src = TyApp src f x
340 source_is (TyQuant _src n kv f) src = TyQuant src n kv f
341 source_is (TyVar _src kv v) src = TyVar src kv v
342 source_is (Term te x) src = Term te $ source_is x src
347 -- | Return the smallest 'Var' not used in given 'Type'.
348 freeTyVar :: Type src cs (h::k) -> Var
349 freeTyVar = (+ 1) . maxTyVar (-1)
351 maxTyVar :: Var -> Type src cs h -> Var
352 maxTyVar m TyConst{} = m
353 maxTyVar m (TyApp _src f a) = maxTyVar m f `max` maxTyVar m a
354 maxTyVar m (TyQuant src _n kv f) = ofKT (maxTyVar m) $ f $ TyVar src kv (-1)
355 maxTyVar m (TyVar _src _kv v) = max m $ if v < 0 then -1 else v + 1
356 maxTyVar m (Term _te x) = maxTyVar m x
361 type Names = Set Name
363 namesTy :: Show_TyConst cs => Type src cs h -> Names
364 namesTy (TyConst _src c) = Set.singleton $ Text.pack $ show_TyConst c
365 namesTy (TyApp _src f x) = namesTy f `Set.union` namesTy x
366 namesTy (TyQuant src _n kv f) = ofKT namesTy $ f $ TyVar src kv (-1)
367 namesTy (TyVar _src _kv v) | v < 0 = Set.empty
368 | otherwise = Set.singleton $ "#" <> Text.pack (show v)
369 namesTy (Term _te x) = namesTy x
371 -- | Infinite list of unique 'Name's:
372 -- @a, b, .., z, a1, b1 .., z1, a2, ..@
375 [ Text.singleton n | n <- ['a'..'z'] ] <>
376 [ Text.pack (n:show i) | n <- ['a'..'z']
377 , i <- [1 :: Int ..] ]
379 -- | Return given 'Name' renamed a bit to avoid
380 -- conflicting with any given 'Names'.
381 freshifyName :: Names -> Name -> Name
382 freshifyName ns "" = freshName ns
384 let ints = [1..] :: [Int] in
387 | suffix <- "" : (show <$> ints)
388 , fresh <- [n <> Text.pack suffix]
389 , fresh `Set.notMember` ns
392 freshName :: Names -> Name
393 freshName ns = List.head $ poolNames List.\\ Set.toList ns
397 = Con_EqType (EType src cs) (EType src cs)
398 | Con_TyApp (EType src cs)
399 | Con_TyCon (KT src cs Constraint)
400 | Con_TyFam (At src TyFamName) [EType src cs]
403 , Inj_Source (EType src cs) src
404 ) => Eq (Con_Type src cs)
409 ) => Show (Con_Type src cs)
412 :: ( Inj_Error (Con_Type src cs) err
413 , Inj_Source (EType src cs) src )
414 => Type src cs (fa::kfa)
415 -> (forall ka f a. (fa :~: f a)
416 -> Type src cs (f::ka -> kfa)
417 -> Type src cs (a::ka)
422 TyApp _src a b -> k Refl (a `source` EType typ) (b `source` EType typ)
423 _ -> Left $ inj_Error $ Con_TyApp (EType typ)
426 :: Inj_Error (Con_Type src cs) err
429 -> ((x :~: y) -> Either err ret) -> Either err ret
433 Nothing -> Left $ inj_Error $
434 Con_EqType (EType x) (EType y)
437 :: ( Inj_Error (Con_Type src cs) err
438 , Inj_Error (Con_Kind src) err
439 , Inj_Source (EType src cs) src
441 => Type src cs (f:: K.Type -> K.Type)
443 -> (forall a. (fa :~: f a)
447 if_EqType1 typ ty_fa k =
448 if_TyApp ty_fa $ \Refl ty_f ty_a ->
449 if_EqKind (kind @(K.Type -> K.Type))
450 (kindTy ty_f) $ \Refl ->
451 if_EqType typ ty_f $ \Refl ->
455 :: ( Inj_Error (Con_Type src cs) err
456 , Inj_Error (Con_Kind src) err
457 , Inj_Source (EType src cs) src )
458 => Type src cs (f:: K.Type -> K.Type -> K.Type)
460 -> (forall a b. (fab :~: f a b)
465 if_EqType2 typ ty_fab k =
466 if_TyApp ty_fab $ \Refl ty_fa ty_b ->
467 if_TyApp ty_fa $ \Refl ty_f ty_a ->
468 if_EqKind (kind @(K.Type -> K.Type -> K.Type))
469 (kindTy ty_f) $ \Refl ->
470 if_EqType typ ty_f $ \Refl ->
474 ( Inj_TyConst cs (->)
475 , Inj_Source (EType src cs) src
476 , Inj_Error (Con_Kind src) err
477 , Inj_Error (Con_Type src cs) err
479 -> (forall a b. (:~:) fab (a -> b)
480 -> Type src cs a -> Type src cs b -> Either err ret)
482 if_TyFun = if_EqType2 (ty @(->))
485 -- | Existential for 'Type'.
486 data EType src cs = forall h. EType (Type src cs h)
488 instance Inj_Source (EType src cs) src => Eq (EType src cs) where
489 EType x == EType y = isJust $ eqKiTy x y
493 ) => Show (EType src cs) where
494 showsPrec p (EType t) = showsPrec p t
497 :: (forall k (h::k). Type src cs h -> Type src cs h)
500 mapEType f (EType t) = EType (f t)
503 :: (forall k (h::k). Type src cs h -> EType src cs)
506 bindEType f (EType t) = f t
509 -- | Existential for 'T' of a known 'Kind'.
510 data KT src cs k = forall (h::k). KT (Type src cs h)
512 type KTerm src cs = KT src cs K.Type
514 instance Eq (KT src cs ki) where
515 KT x == KT y = isJust $ eqTy x y
519 ) => Show (KT src cs ki) where
520 showsPrec p (KT t) = showTy p t
521 instance Inj_Source (EType src cs) src => Inj_Source (KT src cs k) src where
522 inj_Source (KT t) = inj_Source $ EType t
524 unKT :: (forall (h::k). Type src cs h -> a k) -> KT src cs k -> a k
527 ofKT :: (forall (h::k). Type src cs h -> a) -> KT src cs k -> a
531 :: (forall (h::k). Type src cs h -> Type src cs h)
534 mapKT f (KT t) = KT (f t)
537 :: (forall (h::k). Type src cs h -> KT src cs k)
540 bindKT f (KT t) = f t
543 :: (forall (x::ka) (y::kb). Type src cs x -> Type src cs y -> KT src cs kxy)
547 bind2KT f (KT x) (KT y) = f x y
550 data Types src cs (hs::[K.Type]) where
551 TypesZ :: Types src cs '[]
552 TypesS :: Type src cs h
554 -> Types src cs (Proxy h ': hs)
561 => Types src cs hs -> ShowS
562 showTys ts = showString "[" . go ts . showString "]"
564 go :: forall xs. Types src cs xs -> ShowS
565 go TypesZ = showString ""
566 go (TypesS h0 (TypesS h1 hs)) = showTy 10 h0 . showString ", " . showTy 10 h1 . go hs
567 go (TypesS h hs) = showTy 10 h . go hs
572 ) => Show (Types src cs hs) where
573 showsPrec _p = showTys
575 eTypes :: Types src cs hs -> [EType src cs]
577 eTypes (TypesS t ts) = EType t : eTypes ts
581 type family UnProxy (x::K.Type) :: k where
582 UnProxy (Proxy x) = x