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.Typing.Kind
31 import Language.Symantic.Typing.Constant
32 import Language.Symantic.Parsing
34 -- * Type 'T', for both 'Type' and 'Term'
36 -- | /Type of terms/ and… /term/ to be able
37 -- to have polymorphic terms (ie. handle quantified variables).
40 -- * @cs@: /type constants/, fixed at compile time.
41 -- * @h@: indexed Haskell type.
42 -- * @k@: indexed Haskell kind of @h@.
44 -- * 'TyConst': /type constant/, selected amongst @cs@.
46 -- * 'TyApp': /type parameter application/.
48 -- * 'TyQuant': /type universal quantification/ (aka. /type abstraction/):
49 -- used to introduce (and bind) a /type variable/.
51 -- Note that the type indexing is lost (though not kind @k@),
52 -- because GHC cannot represent a quantified type in a type
53 -- aka. impredicative polymorphism.
55 -- * 'TyVar': /type variable/:,
56 -- used to represent a /bounded type variable/,
57 -- when passing through a 'TyQuant'.
59 -- Note that only the kind @k@ is flexible,
60 -- @h@ being set to 'Any' to loose the type indexing
61 -- and enabling the return of a type equality when the 'Var's are the same.
63 -- Note also that there is no DeBruijn encoding done to link 'TyQuant's and 'TyVar's.
65 -- * 'Term': /term/, useful to embed a term
66 -- requiring quantifications and qualifications.
68 -- See also: https://ghc.haskell.org/trac/ghc/wiki/Typeable
69 -- Which currently concludes:
70 -- "Why kind equalities, then? Given the fact that Richard's branch
71 -- doesn't solve this problem, what is it good for?
72 -- It still works wonders in the mono-kinded case,
73 -- such as for decomposing ->.
74 -- It's just that poly-kinded constructors are still a pain."
75 data T (src::K.Type) (cs::[K.Type]) (h::k) where
76 TyConst :: src -> TyConst src cs c
78 TyApp :: src -> Type src cs f
81 -- NOTE: @f x@ decomposition made possible
82 -- at the cost of requiring @TypeInType@.
83 TyQuant :: src -> NameHint
85 -> (forall (v::kv). T src cs v -> KT src cs k)
87 TyVar :: src -> Kind src kv
89 -> Type src cs (Any::kv)
98 type Term src cs h = T src cs (h::K.Type)
100 -- | Remove all top 'Term's.
101 unTerm :: Type src cs (h::k) -> Type src cs (h::k)
102 unTerm (Term _te x) = unTerm x
105 -- | 'Type' constructor to be used with @TypeApplications@ and @NoMonomorphismRestriction@.
106 ty :: forall c src cs. (Source src, Inj_TyConst cs c) => Type src cs c
107 ty = TyConst sourceLess inj_TyConst
108 -- NOTE: The forall brings @c@ first in the type variables,
109 -- which is convenient to use @TypeApplications@.
111 (~>) :: Source src => Inj_TyConst cs (->)
112 => Type src cs a -> Type src cs b -> Type src cs (a -> b)
113 (~>) a b = (ty @(->) `tyApp` a) `tyApp` b
116 -- | Like 'ty', but for a known 'Source'.
117 tySourced :: forall c src cs. (Source src, Inj_TyConst cs c) => src -> Type src cs c
118 tySourced src = TyConst src inj_TyConst
120 -- | Like 'TyApp', but 'sourceLess'.
121 tyApp :: Source src => Type src cs f -> Type src cs a -> Type src cs (f a)
122 tyApp = TyApp sourceLess
125 -- | Like 'TyQuant', but 'sourceLess'.
130 -> (forall (v::kv). Type src cs v -> KT src cs k)
132 tyQuant n kv f = KT $ TyQuant sourceLess n kv f
134 -- | Return the 'Kind' of the given 'Type'.
135 kindTy :: Inj_Source (EType src cs) src => Type src cs (h::k) -> Kind src k
136 kindTy t = kindTyOS t `source` EType t
138 -- | Like 'kindTy' but keep the old 'Source'.
139 kindTyOS :: Type src cs (h::k) -> Kind src k
142 go :: forall cs src k h. Type src cs (h::k) -> Kind src k
144 TyConst _src c -> kindTyConst c
147 KiArrow _src_kf _kx kf -> kf
148 TyQuant src _n k f -> unKT kindTyOS $ f (TyVar src k 0)
150 Term _te x -> kindTyOS x
152 instance -- TestEquality
153 Inj_Source (EType src cs) src
154 => TestEquality (Type src cs) where
156 instance Eq (Type src cs h) where
159 -- | Return a proof when two 'Type's are equals.
161 -- NOTE: 'TyQuant's are not compared:
162 -- they first have to be monomorphized.
163 eqTy :: Type src cs (x::k) -> Type src cs (y::k) -> Maybe (x:~:y)
166 go :: Type src cs (x::k) -> Type src cs (y::k) -> Maybe (x:~:y)
167 go (TyConst _sx x) (TyConst _sy y)
168 | Just Refl <- testEquality x y
170 go (TyApp _sx fx xx) (TyApp _sy fy xy)
171 | Just Refl <- eqKi (kindTyOS fx) (kindTyOS fy)
172 , Just Refl <- go fx fy
173 , Just Refl <- go xx xy
175 go TyQuant{} TyQuant{} = Nothing
177 go v (TyQuant sx _nx kx x::Type src cs vx)
178 (TyQuant sy _ny ky y::Type src cs vy)
179 | Just Refl <- eqKi kx ky
180 , Just Refl <- go (v - 1) (x $ TyVar sx kx v) (y $ TyVar sy ky v)
183 go (TyVar _sx kx x) (TyVar _sy ky y)
184 | Just Refl <- eqKi kx ky
187 -- NOTE: 'Term' are transparent to 'eqTy'.
188 go (Term _tx x) (Term _ty y) | Just Refl <- go x y = Just Refl
189 go (Term _tx x) y | Just Refl <- go x y = Just Refl
190 go x (Term _ty y) | Just Refl <- go x y = Just Refl
193 -- | Return two proofs when two 'Type's are equals:
194 -- one for the type and one for the kind.
195 eqKiTy :: Type src cs (x::kx) -> Type src cs (y::ky) -> Maybe (x:~~:y)
198 go :: Type src cs (x::kx) -> Type src cs (y::ky) -> Maybe (x:~~:y)
199 go (TyConst _sx x) (TyConst _sy y) = eqKiTyConst x y
200 go (TyApp _sx fx xx) (TyApp _sy fy xy)
201 | Just KRefl <- go fx fy
202 , Just KRefl <- go xx xy
204 go TyQuant{} TyQuant{} = Nothing
205 go (TyVar _sx kx _x) (TyVar _sy ky _y)
206 | Just Refl <- eqKi kx ky
208 go (Term _tx x) (Term _ty y) = go x y
212 -- | 'TyConst' to qualify a 'Type'.
213 data (#>) (q::Constraint) (a::K.Type)
217 => Inj_TyConst cs (#>)
218 => Type src cs a -> Type src cs b -> Type src cs (a #> b)
219 (#>) a b = (ty @(#>) `tyApp` a) `tyApp` b
221 -- NOTE: should actually be (-1)
222 -- to compose well with @infixr 0 (->)@
223 -- but this is not allowed by GHC.
227 , Proj_TyConst cs (->)
228 , Proj_TyConst cs (#>)
229 ) => Show (Type src cs h) where
232 showTy :: forall cs src h.
234 , Proj_TyConst cs (->)
235 , Proj_TyConst cs (#>)
236 ) => Int -> Type src cs h -> ShowS
237 showTy pr typ = go Nothing (freeTyVar typ) (Map.empty, namesTy typ) pr typ
240 Maybe (Type src cs p) -- parent Type, used to prettify
241 -> Var -- variable counter (DeBruijn)
242 -> ( Map Var Name -- names of bound variables
243 , Names -- used names : bound variables', free variables' and constants'
248 go _prev _v _vs p (TyConst _src c) = showsPrec p c
249 -- TODO: special infix case for (->), could be abstracted to handle others.
250 go _prev v vs p t@(TyApp _ (TyApp _ (TyConst _ f) a) b)
251 | Just KRefl <- projKiTyConst @_ @(->) f =
253 go (Just t) v vs 1 a .
256 -- TODO: special infix case for (#>), could be abstracted to handle others.
257 go _prev v vs p t@(TyApp _ (TyApp _ (TyConst _ f) a) b)
258 | Just KRefl <- projKiTyConst @_ @(#>) f =
260 go (Just t) v vs 0 a .
263 go _prev v vs p t@(TyApp _src f a) =
265 go (Just t) v vs 11 f .
267 go (Just t) v vs 11 a
268 go prev v (vs, ns) p t@(TyQuant src nv kv f) =
269 let var = TyVar src kv v in
270 let n = freshifyName ns nv in
271 let vs' = Map.insert v n vs in
272 let ns' = Set.insert n ns in
278 _ -> showString "forall") .
280 go (Just t) v (vs', ns') p var .
283 _ -> showString ". ") .
284 go (Just t) (v + 1) (vs', ns') 0 x
285 go _prev _v (vs, _ns) _p (TyVar _src _kv tv) =
286 case Map.lookup tv vs of
287 Nothing -> showString "#" . showsPrec 0 tv
288 Just n -> showString $ Text.unpack n
289 go _prev v vs _p t@(Term _te x) = showBracket True $ go (Just t) v vs 0 x
291 showBracket :: Bool -> ShowS -> ShowS
292 showBracket b p = if b then showChar '{' . p . showChar '}' else p
295 -- | Captures the proof of a 'Constraint'
296 -- (and its dictionaries when it contains type classes):
297 -- pattern matching on the 'TyCon' constructor
298 -- brings the 'Constraint' into scope.
302 -- ** Type 'TyFamName'
303 type TyFamName = Text
306 class Sym (term::K.Type -> K.Type) where
307 sym_lam :: (term a -> term b) -> term (a -> b)
308 sym_app :: term (a -> b) -> (term a -> term b)
309 sym_int :: Int -> term Int
310 sym_id :: term (a -> a)
311 sym_uc :: term (Char -> Char)
312 -- sym_bind :: Monad m => term (m a) -> term (a -> m b) -> term (m b)
313 -- sym_bind :: term (Monad m #> (m a -> (a -> m b) -> m b))
314 sym_bind :: Monad m => term (m a -> (a -> m b) -> m b)
315 sym_const :: term a -> term b -> term a
316 -- sym_comp :: term (b -> c) -> term (a -> c) -> term (a -> b)
317 sym_comp :: term ((b -> c) -> (a -> b) -> a -> c)
320 data TeSym (h::K.Type) = TeSym (forall term. Sym term => term h)
322 instance Source src => Sourced (Type src cs h) where
323 type Source_of (Type src cs h) = src
325 source_of (TyConst src _c) = src
326 source_of (TyApp src _f _x) = src
327 source_of (TyQuant src _n _kv _f) = src
328 source_of (TyVar src _kv _v) = src
329 source_of (Term _te x) = source_of x
331 source_is (TyConst _src c) src = TyConst src c
332 source_is (TyApp _src f x) src = TyApp src f x
333 source_is (TyQuant _src n kv f) src = TyQuant src n kv f
334 source_is (TyVar _src kv v) src = TyVar src kv v
335 source_is (Term te x) src = Term te $ source_is x src
340 -- | Return the smallest 'Var' not used in given 'Type'.
341 freeTyVar :: Type src cs (h::k) -> Var
342 freeTyVar = (+ 1) . maxTyVar (-1)
344 maxTyVar :: Var -> Type src cs h -> Var
345 maxTyVar m TyConst{} = m
346 maxTyVar m (TyApp _src f a) = maxTyVar m f `max` maxTyVar m a
347 maxTyVar m (TyQuant src _n kv f) = ofKT (maxTyVar m) $ f $ TyVar src kv (-1)
348 maxTyVar m (TyVar _src _kv v) = max m $ if v < 0 then -1 else v + 1
349 maxTyVar m (Term _te x) = maxTyVar m x
354 type Names = Set Name
356 namesTy :: Show_TyConst cs => Type src cs h -> Names
357 namesTy (TyConst _src c) = Set.singleton $ Text.pack $ show_TyConst c
358 namesTy (TyApp _src f x) = namesTy f `Set.union` namesTy x
359 namesTy (TyQuant src _n kv f) = ofKT namesTy $ f $ TyVar src kv (-1)
360 namesTy (TyVar _src _kv v) | v < 0 = Set.empty
361 | otherwise = Set.singleton $ "#" <> Text.pack (show v)
362 namesTy (Term _te x) = namesTy x
364 -- | Infinite list of unique 'Name's:
365 -- @a, b, .., z, a1, b1 .., z1, a2, ..@
368 [ Text.singleton n | n <- ['a'..'z'] ] <>
369 [ Text.pack (n:show i) | n <- ['a'..'z']
370 , i <- [1 :: Int ..] ]
372 -- | Return given 'Name' renamed a bit to avoid
373 -- conflicting with any given 'Names'.
374 freshifyName :: Names -> Name -> Name
375 freshifyName ns "" = freshName ns
377 let ints = [1..] :: [Int] in
380 | suffix <- "" : (show <$> ints)
381 , fresh <- [n <> Text.pack suffix]
382 , fresh `Set.notMember` ns
385 freshName :: Names -> Name
386 freshName ns = List.head $ poolNames List.\\ Set.toList ns
390 = Con_EqType (EType src cs) (EType src cs)
391 | Con_TyApp (EType src cs)
392 | Con_TyCon (KT src cs Constraint)
393 | Con_TyFam (At src TyFamName) [EType src cs]
396 , Inj_Source (EType src cs) src
397 ) => Eq (Con_Type src cs)
401 , Proj_TyConst cs (->)
402 , Proj_TyConst cs (#>)
403 ) => Show (Con_Type src cs)
406 :: ( Inj_Error (Con_Type src cs) err
407 , Inj_Source (EType src cs) src )
408 => Type src cs (fa::kfa)
409 -> (forall ka f a. (fa :~: f a)
410 -> Type src cs (f::ka -> kfa)
411 -> Type src cs (a::ka)
416 TyApp _src a b -> k Refl (a `source` EType typ) (b `source` EType typ)
417 _ -> Left $ inj_Error $ Con_TyApp (EType typ)
420 :: Inj_Error (Con_Type src cs) err
423 -> ((x :~: y) -> Either err ret) -> Either err ret
427 Nothing -> Left $ inj_Error $
428 Con_EqType (EType x) (EType y)
431 :: ( Inj_Error (Con_Type src cs) err
432 , Inj_Error (Con_Kind src) err
433 , Inj_Source (EType src cs) src
435 => Type src cs (f:: K.Type -> K.Type)
437 -> (forall a. (fa :~: f a)
441 if_EqType1 typ ty_fa k =
442 if_TyApp ty_fa $ \Refl ty_f ty_a ->
443 if_EqKind (kind @(K.Type -> K.Type))
444 (kindTy ty_f) $ \Refl ->
445 if_EqType typ ty_f $ \Refl ->
449 :: ( Inj_Error (Con_Type src cs) err
450 , Inj_Error (Con_Kind src) err
451 , Inj_Source (EType src cs) src )
452 => Type src cs (f:: K.Type -> K.Type -> K.Type)
454 -> (forall a b. (fab :~: f a b)
459 if_EqType2 typ ty_fab k =
460 if_TyApp ty_fab $ \Refl ty_fa ty_b ->
461 if_TyApp ty_fa $ \Refl ty_f ty_a ->
462 if_EqKind (kind @(K.Type -> K.Type -> K.Type))
463 (kindTy ty_f) $ \Refl ->
464 if_EqType typ ty_f $ \Refl ->
468 ( Inj_TyConst cs (->)
469 , Inj_Source (EType src cs) src
470 , Inj_Error (Con_Kind src) err
471 , Inj_Error (Con_Type src cs) err
473 -> (forall a b. (:~:) fab (a -> b)
474 -> Type src cs a -> Type src cs b -> Either err ret)
476 if_TyFun = if_EqType2 (ty @(->))
479 -- | Existential for 'Type'.
480 data EType src cs = forall h. EType (Type src cs h)
482 instance Inj_Source (EType src cs) src => Eq (EType src cs) where
483 EType x == EType y = isJust $ eqKiTy x y
486 , Proj_TyConst cs (->)
487 , Proj_TyConst cs (#>)
488 ) => Show (EType src cs) where
489 showsPrec p (EType t) = showsPrec p t
492 :: (forall k (h::k). Type src cs h -> Type src cs h)
495 mapEType f (EType t) = EType (f t)
498 :: (forall k (h::k). Type src cs h -> EType src cs)
501 bindEType f (EType t) = f t
504 -- | Existential for 'T' of a known 'Kind'.
505 data KT src cs k = forall (h::k). KT (Type src cs h)
507 type KTerm src cs = KT src cs K.Type
509 instance Eq (KT src cs ki) where
510 KT x == KT y = isJust $ eqTy x y
513 , Proj_TyConst cs (->)
514 , Proj_TyConst cs (#>)
515 ) => Show (KT src cs ki) where
516 showsPrec p (KT t) = showTy p t
517 instance Inj_Source (EType src cs) src => Inj_Source (KT src cs k) src where
518 inj_Source (KT t) = inj_Source $ EType t
520 unKT :: (forall (h::k). Type src cs h -> a k) -> KT src cs k -> a k
523 ofKT :: (forall (h::k). Type src cs h -> a) -> KT src cs k -> a
527 :: (forall (h::k). Type src cs h -> Type src cs h)
530 mapKT f (KT t) = KT (f t)
533 :: (forall (h::k). Type src cs h -> KT src cs k)
536 bindKT f (KT t) = f t
539 :: (forall (x::ka) (y::kb). Type src cs x -> Type src cs y -> KT src cs kxy)
543 bind2KT f (KT x) (KT y) = f x y
546 data Types src cs (hs::[K.Type]) where
547 TypesZ :: Types src cs '[]
548 TypesS :: Type src cs h
550 -> Types src cs (Proxy h ': hs)
556 => Proj_TyConst cs (->)
557 => Proj_TyConst cs (#>)
558 => Types src cs hs -> ShowS
559 showTys ts = showString "[" . go ts . showString "]"
561 go :: forall xs. Types src cs xs -> ShowS
562 go TypesZ = showString ""
563 go (TypesS h0 (TypesS h1 hs)) = showTy 10 h0 . showString ", " . showTy 10 h1 . go hs
564 go (TypesS h hs) = showTy 10 h . go hs
568 , Proj_TyConst cs (->)
569 , Proj_TyConst cs (#>)
570 ) => Show (Types src cs hs) where
571 showsPrec _p = showTys
573 eTypes :: Types src cs hs -> [EType src cs]
575 eTypes (TypesS t ts) = EType t : eTypes ts
579 type family UnProxy (x::K.Type) :: k where
580 UnProxy (Proxy x) = x