1 {-# LANGUAGE ConstraintKinds #-}
2 {-# LANGUAGE PatternSynonyms #-}
3 {-# LANGUAGE PolyKinds #-}
4 {-# LANGUAGE RankNTypes #-}
5 {-# LANGUAGE StandaloneDeriving #-}
6 {-# LANGUAGE UndecidableInstances #-}
7 {-# LANGUAGE UndecidableSuperClasses #-}
8 {-# LANGUAGE ViewPatterns #-}
9 {-# OPTIONS_GHC -Wno-partial-fields #-}
11 module Symantic.Typer.Type where
13 import Control.Applicative (Applicative (..), liftA3)
14 import Control.Monad (Monad (..), sequence)
15 import Control.Monad.Classes as MC ()
16 import Control.Monad.Classes.Run as MC ()
17 import Control.Monad.Trans.Except qualified as MT
18 import Control.Monad.Trans.Identity (IdentityT (..))
19 import Control.Monad.Trans.Reader qualified as MT
20 import Control.Monad.Trans.State qualified as MT
21 import Control.Monad.Trans.Writer.CPS qualified as MT
22 import Data.Bool (Bool, otherwise)
23 import Data.Either (Either (..))
24 import Data.Eq (Eq (..))
25 import Data.Function (id, ($), (.))
26 import Data.Functor (Functor (..), (<$>))
27 import Data.Functor.Constant (Constant (..))
29 import Data.Kind (Constraint, Type)
30 import Data.Map.Strict qualified as Map
31 import Data.Maybe (Maybe (..), isJust)
32 import Data.Monoid (Monoid (..))
33 import Data.Proxy (Proxy (..))
34 import Data.Semigroup (Semigroup (..))
35 import Data.Set qualified as Set
36 import Data.String (String)
38 import Text.Read (Read (..), reads)
39 import Text.Show (Show (..))
40 import Type.Reflection (TypeRep, Typeable, eqTypeRep, typeRep, typeRepKind, (:~~:) (..))
41 import Unsafe.Coerce (unsafeCoerce)
42 import Prelude (error)
43 import Prelude qualified
45 import Symantic.Parser.Source
46 import Symantic.Typer.Eq
47 import Symantic.Typer.List
49 data Const meta a = Const
50 { constType :: TypeRep a
54 instance EqTy (Const meta) (Const meta) where
55 eqTy Const{constType = x} Const{constType = y} = eqTypeRep x y
60 data Var :: forall vK. Type -> [Type] -> vK -> Type where
62 { varZKind :: Kind meta vK
66 Var meta (Proxy (v :: vK) ': ws) (v :: vK)
67 VarS :: Var meta vs v -> Var meta (not_v ': vs) v
68 deriving instance Show meta => Show (Var meta vs v)
70 pattern Var :: () => () => Kind meta vK -> Len ws -> meta -> Var meta vs' (v :: vK)
71 pattern Var{varKind, varNext, varMeta} <- (var -> VarVS VarZ{varZKind = varKind, varZNext = varNext, varZMeta = varMeta})
75 data VarVS meta (v :: vK) = forall vs. VarVS (Var meta vs v)
76 var :: Var meta vs (v :: vK) -> VarVS meta (v :: vK)
77 var v@VarZ{} = VarVS v
80 instance EqTy (Var meta vs) (Var meta vs) where
81 eqTy VarZ{} VarZ{} = Just HRefl
82 eqTy (VarS x) (VarS y) = eqTy x y
85 type VarSem = Type -> [Type] -> Type -> Type
87 -- data VarV (var::VarSem) vs = forall vK (v::vK). VarVSem (var vs v)
88 data VarV meta vs = forall v. VarV (Var meta vs v)
90 class LenVar var where
91 lenVar :: var meta vs a -> Len vs
92 instance LenVar Var where
93 lenVar VarZ{varZNext} = LenS varZNext
94 lenVar (VarS v) = LenS (lenVar v)
96 class LenVar var => AllocVars var where
97 allocVarsL :: Len len -> var meta vs x -> var meta (len ++ vs) x
98 allocVarsR :: Len len -> var meta vs x -> var meta (vs ++ len) x
99 instance AllocVars Var where
100 allocVarsL LenZ v = v
101 allocVarsL (LenS len) v = VarS (allocVarsL len v)
103 allocVarsR len VarZ{..} = VarZ{varZNext = addLen varZNext len, ..}
104 allocVarsR len (VarS v) = VarS (allocVarsR len v)
109 xVar meta xVS (x :: xK) ->
110 yVar meta yVS (y :: yK) ->
111 ( xVar meta (xVS ++ yVS) x
112 , yVar meta (xVS ++ yVS) y
115 ( allocVarsR (lenVar y) x
116 , allocVarsL (lenVar x) y
119 -- ** Type 'IndexVar'
121 -- | Index of a 'Var'.
124 indexVar :: Var meta vs v -> Int
126 indexVar (VarS v) = 1 Prelude.+ indexVar v
128 -- instance KindOf (Var meta vs) where
131 -- go :: forall vs2 aK a. Var meta vs2 (Proxy (a::aK)) -> TypeRep aK
132 -- go VarZ{varKind} = varKind
133 -- go (VarS v) = go v
136 type Vars meta vs = Map.Map Name (VarV meta vs)
138 lookupVar :: Name -> Vars meta vs -> Maybe (VarV meta vs)
139 lookupVar = Map.lookup
141 insertVar :: Name -> VarV meta vs -> Vars meta vs -> Vars meta vs
142 insertVar = Map.insert
146 -- | List of 'Var's, used to change the context of a 'Var'
147 -- when removing unused 'Var's.
148 data UsedVars oldVS meta newVS a where
149 UsedVarsZ :: UsedVars oldVS meta '[] a
151 Var meta oldVS (v :: vK) ->
152 UsedVars oldVS meta newVS a ->
153 UsedVars oldVS meta (Proxy (v :: vK) ': newVS) a
155 instance LenVar (UsedVars oldVS) where
156 lenVar UsedVarsZ = LenZ
157 lenVar (UsedVarsS _v oldVS) = LenS $ lenVar oldVS
160 Var meta oldVS (v :: vK) ->
161 UsedVars oldVS meta newVS a ->
162 Maybe (Var meta newVS (v :: vK))
163 lookupUsedVars _v UsedVarsZ = Nothing
164 lookupUsedVars v (UsedVarsS v' us) = do
168 Var{varKind, varMeta} ->
171 { varZNext = lenVar us
175 Nothing -> VarS Data.Functor.<$> lookupUsedVars v us
179 UsedVars vs meta us a ->
180 Maybe (UsedVars vs meta (Proxy v ': us) a)
181 insertUsedVars v vs =
182 case lookupUsedVars v vs of
184 Nothing -> Just (UsedVarsS v vs)
186 -- * Class 'VarOccursIn'
188 -- | Test whether a given 'Var' occurs within @(t)@.
189 class VarOccursIn (t :: Type -> [Type] -> aK -> Type) where
190 varOccursIn :: Var meta vs v -> t meta vs a -> Bool
192 -- * Class 'UsedVarsOf'
193 class UsedVarsOf t where
195 UsedVars vs meta oldVS a ->
197 (forall newVS. UsedVars vs meta newVS a -> ret) ->
202 -- Use a CUSK, because it's a polymorphically recursive type,
203 -- See https://ryanglscott.github.io/2020/01/05/five-benefits-to-using-standalonekindsignatures/
204 data Ty :: forall aK. Type -> [Type] -> aK -> Type where
205 TyConst :: {tyConst :: Const meta a, tyConstLen :: Len vs} -> Ty meta vs a
206 TyVar :: {tyVar :: Var meta vs a, tyVarName :: Name} -> Ty meta vs a
207 TyApp :: {tyAppFun :: Ty meta vs f, tyAppArg :: Ty meta vs a} -> Ty meta vs (f a)
212 typeOf :: Monoid meta => Ty meta '[] a
213 instance (Tyable a, Tyable b) => Tyable (a b) where
214 typeOf = TyApp (typeOf @a) (typeOf @b)
215 instance {-# OVERLAPPABLE #-} Typeable a => Tyable a where
216 typeOf = TyConst{tyConst = Const{constType = typeRep, constMeta = mempty}, tyConstLen = LenZ}
220 forall k (fun :: k) meta vs.
230 , fun ~~ (arg -> res)
232 -- , r2 ~ LiftedRep {- fixme: remove those 2 constraints -}
237 pattern FUN arg res <-
241 { tyAppFun = TyConst{tyConst = Const{constType = eqTypeRep (typeRep @(->)) -> Just HRefl}}
247 -- where FUN arg res =
249 -- { tyAppFun = TyApp
250 -- { tyAppFun = TyConst
251 -- { tyConstLen=lenVar arg
252 -- , tyConst=Const{ constType=typeRep @(->)
253 -- , constMeta=(mempty::meta)}
260 deriving instance Show meta => Show (Ty meta vs a)
262 -- type instance SourceOf (Ty vs src t) = src
263 instance LenVar Ty where
264 lenVar TyConst{tyConstLen} = tyConstLen
265 lenVar TyApp{tyAppFun} = lenVar tyAppFun
266 lenVar TyVar{tyVar} = lenVar tyVar
268 -- lenVars (TyFam l _f _as) = l
269 instance AllocVars Ty where
270 allocVarsL len ty@TyConst{..} = ty{tyConstLen = addLen len tyConstLen}
271 allocVarsL len TyApp{..} = TyApp{tyAppFun = allocVarsL len tyAppFun, tyAppArg = allocVarsL len tyAppArg}
272 allocVarsL len ty@TyVar{..} = ty{tyVar = allocVarsL len tyVar}
274 -- allocVarsL len (TyFam l f as) = TyFam (addLen len l) f $ allocVarsL len `mapTys` as
276 allocVarsR len ty@TyConst{..} = ty{tyConstLen = addLen tyConstLen len}
277 allocVarsR len TyApp{..} = TyApp{tyAppFun = allocVarsR len tyAppFun, tyAppArg = allocVarsR len tyAppArg, ..}
278 allocVarsR len ty@TyVar{..} = ty{tyVar = allocVarsR len tyVar}
280 -- allocVarsR len (TyFam l f as) = TyFam (addLen l len) f $ allocVarsR len `mapTys` as
281 instance VarOccursIn Ty where
282 varOccursIn v TyVar{tyVar = v'} | Just{} <- v `eqTy` v' = False
283 varOccursIn _v TyVar{} = False
284 varOccursIn _v TyConst{} = False
285 varOccursIn v TyApp{tyAppFun = f, tyAppArg = a} = varOccursIn v f Prelude.|| varOccursIn v a
287 -- varOccursIn v (TyFam _src _len _fam as) = varOccursIn v as
288 instance UsedVarsOf Ty where
289 usedVarsOf vs TyConst{} k = k vs
290 usedVarsOf vs TyApp{tyAppFun = f, tyAppArg = a} k =
291 usedVarsOf vs f $ \vs' ->
293 usedVarsOf vs TyVar{tyVar = v} k =
294 case insertUsedVars v vs of
298 -- usedVarsOf vs (TyFam _src _len _fam as) k = usedVarsOf vs as k
302 -- | Existential for 'Type'.
303 data TyT meta vs = forall a. TyT (Ty meta vs a)
305 -- type instance SourceOf (TyT vs src) = src
306 instance Eq (TyT meta vs) where
307 TyT x == TyT y = isJust $ eqTy x y
308 instance Show meta => Show (TyT meta vs) where
309 showsPrec p (TyT x) = showsPrec p x
312 type Kind meta a = Ty meta '[] a
315 type KindK meta = TyT meta '[]
318 data TyVT meta = forall vs a. TyVT (Ty meta vs a)
320 deriving instance Show meta => Show (TyVT meta)
321 instance Eq (TyVT m) where
322 TyVT x == TyVT y = isJust (eqTy x' y')
324 (x', y') = appendVars x y
326 -- instance (Monoid src) => EqTy (MT.Writer src) (MT.Writer src) where
327 -- eqTy x y = eqTy (unSourced x) (unSourced y)
328 instance EqTy (Ty meta vs) (Ty meta vs) where
329 eqTy TyConst{tyConst = x} TyConst{tyConst = y} = eqTy x y
330 eqTy TyVar{tyVar = x} TyVar{tyVar = y} = eqTy x y
331 eqTy TyApp{tyAppFun = xF, tyAppArg = xA} TyApp{tyAppFun = yF, tyAppArg = yA}
332 | Just HRefl <- eqTy xF yF
333 , Just HRefl <- eqTy xA yA =
337 -- eqTy (TyFam _ _lx xF xA) (TyFam _ _ly yF yA)
338 -- | Just HRefl <- eqTypeRep xF yF
339 -- , Just HRefl <- eqTys xA yA
341 -- -- NOTE: 'TyFam' is expanded as much as possible.
342 -- eqTy x@TyFam{} y = eqTy (expandFam x) y
343 -- eqTy x y@TyFam{} = eqTy x (expandFam y)
346 data Tys (as :: [Type]) meta vs (a :: aK) where
347 TysZ :: Tys '[] meta vs a
348 TysS :: Ty meta vs a -> Tys as meta vs b -> Tys (Proxy a ': as) meta vs b
351 -- type instance SourceOf (Tys vs src ts) = src
352 -- instance ConstsOf (Tys meta vs ts) where
353 -- constsOf TysZ = Set.empty
354 -- constsOf (TysS t ts) = constsOf t `Set.union` constsOf ts
355 instance UsedVarsOf (Tys as) where
356 usedVarsOf vs TysZ k = k vs
357 usedVarsOf vs (TysS t ts) k =
358 usedVarsOf vs t $ \vs' ->
360 instance VarOccursIn (Tys as) where
361 varOccursIn _v TysZ = False
362 varOccursIn v (TysS t ts) = varOccursIn v t Prelude.|| varOccursIn v ts
364 -- ** Type family 'FunArg'
365 type family FunArg (fun :: Type) :: Type where
366 FunArg (q #> f) = FunArg f
369 -- ** Type family 'FunRes'
370 type family FunRes (fun :: Type) :: Type where
371 FunRes (q #> f) = FunRes f
374 -- -- | Return, when the given 'Type' is a function,
375 -- -- the argument of that function.
378 -- SourceInj (TyVT src) src =>
379 -- --Constable (->) =>
381 -- Maybe ( Type src tys (FunArg t)
382 -- , Type src tys (FunRes t) )
383 -- unTyFun ty_ini = go ty_ini
387 -- Maybe ( Type src tys (FunArg x)
388 -- , Type src tys (FunRes x) )
389 -- go (TyApp _ (TyApp _ (TyConst _ _ f) a) b)
390 -- | Just HRefl <- proj_ConstKi @(K (->)) @(->) f
391 -- = Just ((a `withSource` TyVT ty_ini), (b `withSource` TyVT ty_ini))
392 -- go (TyApp _ (TyApp _ (TyConst _ _ f) _a) b)
393 -- | Just HRefl <- proj_ConstKi @(K (#>)) @(#>) f
395 -- go TyApp{} = Nothing
396 -- go TyConst{} = Nothing
397 -- go TyVar{} = Nothing
398 -- go TyFam{} = Nothing
401 forall kc (c :: kc) u meta.
403 -- (kc ~ Type_of_Ty (Ty_of_Type kc)) =>
404 -- KindInjP (Ty_of_Type kc) =>
407 proj_ConstKi = eqTypeRep (typeRep @c) . constType
409 -- HRefl <- eqTy ku kc -- $ kindInjP @(Ty_of_Type kc) ()
410 -- HRefl :: u:~~:c <- eqT
415 -- | /Type constant/ to qualify a 'Type'.
416 newtype (#>) (q :: Constraint) (a :: Type) = Qual (q => a)
418 -- | Qualify a 'Type'.
419 (#>) :: Monoid meta => Ty meta vs q -> Ty meta vs t -> Ty meta vs (q #> t)
421 -- (tyConstLen @(K (#>)) @(#>) (lenVars q) `tyApp` q) `tyApp` t
425 { tyAppFun = TyConst{tyConst = Const{constType = typeRep @(#>), constMeta = mempty}, tyConstLen = lenVar q}
433 -- NOTE: should actually be (-1)
434 -- to compose well with @infixr 0 (->)@
435 -- but this is not allowed by GHC.
439 -- | 'Constraint' union.
440 class ((x, y) :: Constraint) => x # y
442 instance ((x, y) :: Constraint) => x # y
444 -- | Unify two 'K.Constraint's.
445 (#) :: Monoid meta => Ty meta vs qx -> Ty meta vs qy -> Ty meta vs (qx # qy)
447 -- (tyConstLen @(K (#)) @(#) (lenVars a) `tyApp` a) `tyApp` b
451 { tyAppFun = TyConst{tyConst = Const{constType = typeRep @(#), constMeta = mempty}, tyConstLen = lenVar a}
460 class KindOf (ty :: Type -> [Type] -> aK -> Type) where
461 -- | Return the kind of the given 'Var'.
463 -- Provenanceable (ProvenanceKindOf t) m =>
464 -- MC.MonadWriter (ProvenanceKindOf t) m =>
465 ty meta vs (a :: aK) ->
468 instance KindOf Var where
469 kindOf Var{varKind} = varKind
470 instance KindOf Ty where
471 kindOf TyConst{tyConst = c} = TyConst{tyConst = c{constType = typeRepKind (constType c)}, tyConstLen = LenZ}
472 kindOf TyApp{tyAppFun = f} = case kindOf f of
474 kindOf TyVar{tyVar = Var{varKind, varMeta}} = varKind
476 -- kindOf (TyFam _src _len fam _as) = kindOfConst fam