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.Monad.Classes as MC ()
14 import Control.Monad.Classes.Run as MC ()
15 import Data.Eq (Eq (..))
16 import Data.Function (($))
17 import Data.Functor ((<$>))
18 import Data.Map.Strict qualified as Map
19 import Data.Maybe (Maybe (..), isJust)
20 import Data.Monoid (Monoid (..))
21 import Data.Proxy (Proxy (..))
22 import Data.Semigroup (Semigroup (..))
23 import Data.String (String)
25 import Text.Show (Show (..))
26 import Type.Reflection (TypeRep, Typeable, eqTypeRep, typeRep, typeRepKind, (:~~:) (..), pattern App)
27 import Prelude qualified
29 import Symantic.Typer.Eq
30 import Symantic.Typer.List
32 data WithProv prov a = WithProv {withProv :: prov, unWithProv :: a}
44 data Var :: forall vK. Prov -> [Type] -> vK -> Type where
46 { varZKind :: Kind prov vK
49 Var prov (Proxy (v :: vK) ': ws) (v :: vK)
50 VarS :: Var prov vs v -> Var prov (not_v ': vs) v
51 deriving instance Show prov => Show (Var prov vs v)
53 pattern Var :: () => () => Kind prov vK -> Len ws -> Var prov vs' (v :: vK)
54 pattern Var{varKind, varNext} <- (var -> VarVS VarZ{varZKind = varKind, varZNext = varNext})
58 data VarVS prov (v :: vK) = forall vs. VarVS (Var prov vs v)
59 var :: Var prov vs (v :: vK) -> VarVS prov (v :: vK)
60 var v@VarZ{} = VarVS v
63 instance EqTy (Var prov vs) (Var prov vs) where
64 eqTy VarZ{} VarZ{} = Just HRefl
65 eqTy (VarS x) (VarS y) = eqTy x y
68 type VarSem = Type -> [Type] -> Type -> Type
70 -- data VarV (var::VarSem) vs = forall vK (v::vK). VarVSem (var vs v)
71 data VarV prov vs = forall v. VarV (Var prov vs v)
73 class LenVar var where
74 lenVar :: var prov vs a -> Len vs
75 instance LenVar Var where
76 lenVar VarZ{varZNext} = LenS varZNext
77 lenVar (VarS v) = LenS (lenVar v)
79 class LenVar var => AllocVars var where
80 allocVarsL :: Len len -> var prov vs x -> var prov (len ++ vs) x
81 allocVarsR :: Len len -> var prov vs x -> var prov (vs ++ len) x
82 instance AllocVars Var where
84 allocVarsL (LenS len) v = VarS (allocVarsL len v)
86 allocVarsR len VarZ{..} = VarZ{varZNext = addLen varZNext len, ..}
87 allocVarsR len (VarS v) = VarS (allocVarsR len v)
92 xVar prov xVS (x :: xK) ->
93 yVar prov yVS (y :: yK) ->
94 ( xVar prov (xVS ++ yVS) x
95 , yVar prov (xVS ++ yVS) y
98 ( allocVarsR (lenVar y) x
99 , allocVarsL (lenVar x) y
102 -- ** Type 'IndexVar'
104 -- | Index of a 'Var'.
107 indexVar :: Var prov vs v -> Int
109 indexVar (VarS v) = 1 Prelude.+ indexVar v
111 -- instance KindOf (Var prov vs) where
114 -- go :: forall vs2 aK a. Var prov vs2 (Proxy (a::aK)) -> TypeRep aK
115 -- go VarZ{varKind} = varKind
116 -- go (VarS v) = go v
119 type Vars prov vs = Map.Map Name (VarV prov vs)
121 lookupVar :: Name -> Vars prov vs -> Maybe (VarV prov vs)
122 lookupVar = Map.lookup
124 insertVar :: Name -> VarV prov vs -> Vars prov vs -> Vars prov vs
125 insertVar = Map.insert
129 -- | List of 'Var's, used to change the context of a 'Var'
130 -- when removing unused 'Var's.
131 data UsedVars oldVS prov newVS a where
132 UsedVarsZ :: UsedVars oldVS prov '[] a
134 Var prov oldVS (v :: vK) ->
135 UsedVars oldVS prov newVS a ->
136 UsedVars oldVS prov (Proxy (v :: vK) ': newVS) a
138 instance LenVar (UsedVars oldVS) where
139 lenVar UsedVarsZ = LenZ
140 lenVar (UsedVarsS _v oldVS) = LenS $ lenVar oldVS
143 Var prov oldVS (v :: vK) ->
144 UsedVars oldVS prov newVS a ->
145 Maybe (Var prov newVS (v :: vK))
146 lookupUsedVars _v UsedVarsZ = Nothing
147 lookupUsedVars v (UsedVarsS v' us) = do
154 { varZNext = lenVar us
157 Nothing -> VarS Data.Functor.<$> lookupUsedVars v us
161 UsedVars vs prov us a ->
162 Maybe (UsedVars vs prov (Proxy v ': us) a)
163 insertUsedVars v vs =
164 case lookupUsedVars v vs of
166 Nothing -> Just (UsedVarsS v vs)
168 -- * Class 'VarOccursIn'
170 -- | Test whether a given 'Var' occurs within @(t)@.
171 class VarOccursIn (t :: Type -> [Type] -> aK -> Type) where
172 varOccursIn :: Var prov vs v -> t prov vs a -> Bool
174 -- * Class 'UsedVarsOf'
175 class UsedVarsOf t where
177 UsedVars vs prov oldVS a ->
179 (forall newVS. UsedVars vs prov newVS a -> ret) ->
184 -- Use a CUSK, because it's a polymorphically recursive type,
185 -- See https://ryanglscott.github.io/2020/01/05/five-benefits-to-using-standalonekindsignatures/
186 data Ty :: forall aK. Prov -> [Type] -> aK -> Type where
187 TyConst :: {tyConst :: Const a, tyConstLen :: Len vs} -> Ty prov vs a
188 TyVar :: {tyVar :: Var prov vs a, tyVarName :: Name} -> Ty prov vs a
189 TyApp :: {tyAppFun :: Ty prov vs f, tyAppArg :: Ty prov vs a} -> Ty prov vs (f a)
190 TyProv :: {tyProv :: prov, tyUnProv :: Ty prov vs a} -> Ty prov vs a
193 tyOfTypeRep :: Len vs -> TypeRep a -> Ty prov vs a
194 tyOfTypeRep len ty = case ty of
195 App f x -> TyApp{tyAppFun = tyOfTypeRep len f, tyAppArg = tyOfTypeRep len x}
196 constType -> TyConst{tyConst = constType, tyConstLen = len}
198 -- | Monomorphic 'Ty' from a 'Typeable'.
199 monoTy :: forall {aK} (a :: aK) prov. Typeable a => Ty prov '[] a
200 monoTy = tyOfTypeRep LenZ typeRep
202 aTy :: LenInj vs => Monoid prov => Ty prov (Proxy a ': vs) (a :: Type)
203 bTy :: LenInj vs => Monoid prov => Ty prov (Proxy a ': Proxy b ': vs) (b :: Type)
204 cTy :: LenInj vs => Monoid prov => Ty prov (Proxy a : Proxy b : Proxy c : vs) (c :: Type)
205 dTy :: LenInj vs => Monoid prov => Ty prov (Proxy a : Proxy b : Proxy c : Proxy d : vs) (d :: Type)
206 aTy = TyVar{tyVar = VarZ{varZKind = monoTy @Type, varZNext = lenInj}, tyVarName = "a"}
207 bTy = TyVar{tyVar = VarS $ VarZ{varZKind = monoTy @Type, varZNext = lenInj}, tyVarName = "b"}
208 cTy = TyVar{tyVar = VarS $ VarS $ VarZ{varZKind = monoTy @Type, varZNext = lenInj}, tyVarName = "c"}
209 dTy = TyVar{tyVar = VarS $ VarS $ VarS $ VarZ{varZKind = monoTy @Type, varZNext = lenInj}, tyVarName = "d"}
211 pattern SkipTyProv :: () => () => Ty prov vs a -> Ty prov vs a
212 pattern SkipTyProv ty <- (skipTyProv -> ty)
213 {-# COMPLETE SkipTyProv #-}
215 skipTyProv :: Ty prov vs a -> Ty prov vs a
216 skipTyProv TyProv{tyUnProv} = tyUnProv
221 forall k (fun :: k) prov vs.
231 , fun ~~ (arg -> res)
233 -- , r2 ~ LiftedRep {- fixme: remove those 2 constraints -}
238 pattern FUN arg res <-
244 { tyAppFun = SkipTyProv TyConst{tyConst = eqTypeRep (typeRep @(->)) -> Just HRefl}
250 (~>) :: Monoid prov => Ty prov vs a -> Ty prov vs b -> Ty prov vs (a -> b)
256 TyConst{tyConst = typeRep, tyConstLen = (lenVar arg)}
263 deriving instance Show prov => Show (Ty prov vs a)
265 -- type instance SourceOf (Ty vs src t) = src
266 instance LenVar Ty where
267 lenVar TyConst{tyConstLen} = tyConstLen
268 lenVar TyApp{tyAppFun} = lenVar tyAppFun
269 lenVar TyVar{tyVar} = lenVar tyVar
270 lenVar TyProv{tyUnProv} = lenVar tyUnProv
272 -- lenVars (TyFam l _f _as) = l
273 instance AllocVars Ty where
274 allocVarsL len ty@TyConst{..} = ty{tyConstLen = addLen len tyConstLen}
275 allocVarsL len TyApp{..} = TyApp{tyAppFun = allocVarsL len tyAppFun, tyAppArg = allocVarsL len tyAppArg}
276 allocVarsL len ty@TyVar{..} = ty{tyVar = allocVarsL len tyVar}
277 allocVarsL len TyProv{..} = TyProv{tyProv, tyUnProv = allocVarsL len tyUnProv}
279 -- allocVarsL len (TyFam l f as) = TyFam (addLen len l) f $ allocVarsL len `mapTys` as
281 allocVarsR len ty@TyConst{..} = ty{tyConstLen = addLen tyConstLen len}
282 allocVarsR len TyApp{..} = TyApp{tyAppFun = allocVarsR len tyAppFun, tyAppArg = allocVarsR len tyAppArg, ..}
283 allocVarsR len ty@TyVar{..} = ty{tyVar = allocVarsR len tyVar}
284 allocVarsR len TyProv{..} = TyProv{tyProv, tyUnProv = allocVarsR len tyUnProv}
286 -- allocVarsR len (TyFam l f as) = TyFam (addLen l len) f $ allocVarsR len `mapTys` as
288 instance VarOccursIn Ty where
289 varOccursIn v TyVar{tyVar = v'} | Just{} <- v `eqTy` v' = False
290 varOccursIn _v TyVar{} = False
291 varOccursIn _v TyConst{} = False
292 varOccursIn v TyApp{tyAppFun = f, tyAppArg = a} = varOccursIn v f Prelude.|| varOccursIn v a
293 varOccursIn v TyProv{..} = varOccursIn v tyUnProv
295 -- varOccursIn v (TyFam _src _len _fam as) = varOccursIn v as
296 instance UsedVarsOf Ty where
297 usedVarsOf vs TyConst{} k = k vs
298 usedVarsOf vs TyApp{tyAppFun = f, tyAppArg = a} k =
299 usedVarsOf vs f $ \vs' ->
301 usedVarsOf vs TyVar{tyVar = v} k =
302 case insertUsedVars v vs of
305 usedVarsOf vs TyProv{tyUnProv} k = usedVarsOf vs tyUnProv k
307 -- usedVarsOf vs (TyFam _src _len _fam as) k = usedVarsOf vs as k
311 -- | Existential for 'Type'.
312 data TyT prov vs = forall a. TyT (Ty prov vs a)
314 -- type instance SourceOf (TyT vs src) = src
315 instance Eq (TyT prov vs) where
316 TyT x == TyT y = isJust $ eqTy x y
317 instance Show prov => Show (TyT prov vs) where
318 showsPrec p (TyT x) = showsPrec p x
321 type Kind prov a = Ty prov '[] a
324 type KindK prov = TyT prov '[]
327 data TyVT prov = forall vs a. TyVT (Ty prov vs a)
329 deriving instance Show prov => Show (TyVT prov)
330 instance Eq (TyVT m) where
331 TyVT x == TyVT y = isJust (eqTy x' y')
333 (x', y') = appendVars x y
335 -- instance (Monoid src) => EqTy (MT.Writer src) (MT.Writer src) where
336 -- eqTy x y = eqTy (unSourced x) (unSourced y)
337 instance EqTy (Ty prov vs) (Ty prov vs) where
340 go :: forall xK xT yK yT. Ty prov vs (xT :: xK) -> Ty prov vs (yT :: yK) -> Maybe (xT :~~: yT)
341 go TyConst{tyConst = x} TyConst{tyConst = y} = eqTy x y
342 go TyVar{tyVar = x} TyVar{tyVar = y} = eqTy x y
343 go TyApp{tyAppFun = xF, tyAppArg = xA} TyApp{tyAppFun = yF, tyAppArg = yA}
344 | Just HRefl <- go xF yF
345 , Just HRefl <- go xA yA =
347 go TyProv{tyUnProv = x} y = go x y
348 go x TyProv{tyUnProv = y} = go x y
351 -- eqTy (TyFam _ _lx xF xA) (TyFam _ _ly yF yA)
352 -- | Just HRefl <- eqTypeRep xF yF
353 -- , Just HRefl <- eqTys xA yA
355 -- -- NOTE: 'TyFam' is expanded as much as possible.
356 -- eqTy x@TyFam{} y = eqTy (expandFam x) y
357 -- eqTy x y@TyFam{} = eqTy x (expandFam y)
360 data Tys (as :: [Type]) prov vs (a :: aK) where
361 TysZ :: Tys '[] prov vs a
362 TysS :: Ty prov vs a -> Tys as prov vs b -> Tys (Proxy a ': as) prov vs b
365 -- type instance SourceOf (Tys vs src ts) = src
366 -- instance ConstsOf (Tys prov vs ts) where
367 -- constsOf TysZ = Set.empty
368 -- constsOf (TysS t ts) = constsOf t `Set.union` constsOf ts
369 instance UsedVarsOf (Tys as) where
370 usedVarsOf vs TysZ k = k vs
371 usedVarsOf vs (TysS t ts) k =
372 usedVarsOf vs t $ \vs' ->
374 instance VarOccursIn (Tys as) where
375 varOccursIn _v TysZ = False
376 varOccursIn v (TysS t ts) = varOccursIn v t Prelude.|| varOccursIn v ts
378 -- ** Type family 'FunArg'
379 type family FunArg (fun :: Type) :: Type where
380 FunArg (q #> f) = FunArg f
383 -- ** Type family 'FunRes'
384 type family FunRes (fun :: Type) :: Type where
385 FunRes (q #> f) = FunRes f
388 -- -- | Return, when the given 'Type' is a function,
389 -- -- the argument of that function.
392 -- SourceInj (TyVT src) src =>
393 -- --Constable (->) =>
395 -- Maybe ( Type src tys (FunArg t)
396 -- , Type src tys (FunRes t) )
397 -- unTyFun ty_ini = go ty_ini
401 -- Maybe ( Type src tys (FunArg x)
402 -- , Type src tys (FunRes x) )
403 -- go (TyApp _ (TyApp _ (TyConst _ _ f) a) b)
404 -- | Just HRefl <- proj_ConstKi @(K (->)) @(->) f
405 -- = Just ((a `withSource` TyVT ty_ini), (b `withSource` TyVT ty_ini))
406 -- go (TyApp _ (TyApp _ (TyConst _ _ f) _a) b)
407 -- | Just HRefl <- proj_ConstKi @(K (#>)) @(#>) f
409 -- go TyApp{} = Nothing
410 -- go TyConst{} = Nothing
411 -- go TyVar{} = Nothing
412 -- go TyFam{} = Nothing
415 forall kc (c :: kc) u.
417 -- (kc ~ Type_of_Ty (Ty_of_Type kc)) =>
418 -- KindInjP (Ty_of_Type kc) =>
421 proj_ConstKi = eqTypeRep (typeRep @c)
425 -- | /Type constant/ to qualify a 'Type'.
426 newtype (#>) (q :: Constraint) (a :: Type) = Qual (q => a)
428 -- | Qualify a 'Type'.
429 (#>) :: Monoid prov => Ty prov vs q -> Ty prov vs t -> Ty prov vs (q #> t)
431 -- (tyConstLen @(K (#>)) @(#>) (lenVars q) `tyApp` q) `tyApp` t
435 { tyAppFun = TyConst{tyConst = typeRep @(#>), tyConstLen = lenVar q}
443 -- NOTE: should actually be (-1)
444 -- to compose well with @infixr 0 (->)@
445 -- but this is not allowed by GHC.
449 -- | 'Constraint' union.
450 class ((x, y) :: Constraint) => x # y
452 instance ((x, y) :: Constraint) => x # y
454 -- | Unify two 'K.Constraint's.
455 (#) :: Monoid prov => Ty prov vs qx -> Ty prov vs qy -> Ty prov vs (qx # qy)
457 -- (tyConstLen @(K (#)) @(#) (lenVars a) `tyApp` a) `tyApp` b
461 { tyAppFun = TyConst{tyConst = typeRep @(#), tyConstLen = lenVar a}
470 class KindOf (ty :: Prov -> [Type] -> aK -> Type) where
471 -- | Return the kind of the given 'Var'.
474 ProvenanceKindOf ty prov =>
476 ty prov vs (a :: aK) ->
477 Kind prov (aK :: Type)
479 instance KindOf Var where
480 kindOf v@Var{varKind} = TyProv (provenanceKindOf v) varKind
481 instance KindOf Ty where
482 kindOf ty = TyProv (provenanceKindOf ty) (go ty)
486 Ty prov vs (a :: aK) ->
487 Kind prov (aK :: Type)
488 go TyConst{tyConst = constType :: Const (a :: aK)} =
489 tyOfTypeRep LenZ (typeRepKind constType)
490 go TyApp{tyAppFun = f} = case go f of
496 { tyAppFun = SkipTyProv TyConst{tyConst = eqTypeRep (typeRep @(->)) -> Just HRefl}
500 t -> Prelude.error $ "here: " <> show t
501 go TyVar{..} = varKind tyVar
502 go TyProv{..} = go tyUnProv
504 -- ** Class 'ProvenanceKindOf'
505 class ProvenanceKindOf (ty :: Prov -> [Type] -> aK -> Type) prov where
506 provenanceKindOf :: ty prov vs (a :: aK) -> prov
507 instance ProvenanceKindOf ty () where
508 provenanceKindOf _ = ()
509 instance ProvenanceKindOf Ty String where
510 provenanceKindOf = show
511 instance ProvenanceKindOf Var String where
512 provenanceKindOf = show
514 -- kindOf (TyFam _src _len fam _as) = kindOfConst fam