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 GHC.Stack (HasCallStack)
27 import Text.Show (Show (..))
28 import Type.Reflection (TypeRep, Typeable, eqTypeRep, typeRep, typeRepKind, (:~~:) (..), pattern App)
29 import Prelude (error)
30 import Prelude qualified
32 import Symantic.Typer.Eq
33 import Symantic.Typer.List
35 data Const meta (a :: aK) =
38 { constType :: TypeRep a
43 deriving instance Show meta => Show (Const meta a)
44 instance EqTy (Const meta) (Const meta) where
45 eqTy Const{constType = x} Const{constType = y} = eqTypeRep x y
50 data Var :: forall vK. Type -> [Type] -> vK -> Type where
52 { varZKind :: Kind meta vK
56 Var meta (Proxy (v :: vK) ': ws) (v :: vK)
57 VarS :: Var meta vs v -> Var meta (not_v ': vs) v
58 deriving instance Show meta => Show (Var meta vs v)
60 pattern Var :: () => () => Kind meta vK -> Len ws -> meta -> Var meta vs' (v :: vK)
61 pattern Var{varKind, varNext, varMeta} <- (var -> VarVS VarZ{varZKind = varKind, varZNext = varNext, varZMeta = varMeta})
65 data VarVS meta (v :: vK) = forall vs. VarVS (Var meta vs v)
66 var :: Var meta vs (v :: vK) -> VarVS meta (v :: vK)
67 var v@VarZ{} = VarVS v
70 instance EqTy (Var meta vs) (Var meta vs) where
71 eqTy VarZ{} VarZ{} = Just HRefl
72 eqTy (VarS x) (VarS y) = eqTy x y
75 type VarSem = Type -> [Type] -> Type -> Type
77 -- data VarV (var::VarSem) vs = forall vK (v::vK). VarVSem (var vs v)
78 data VarV meta vs = forall v. VarV (Var meta vs v)
80 class LenVar var where
81 lenVar :: var meta vs a -> Len vs
82 instance LenVar Var where
83 lenVar VarZ{varZNext} = LenS varZNext
84 lenVar (VarS v) = LenS (lenVar v)
86 class LenVar var => AllocVars var where
87 allocVarsL :: Len len -> var meta vs x -> var meta (len ++ vs) x
88 allocVarsR :: Len len -> var meta vs x -> var meta (vs ++ len) x
89 instance AllocVars Var where
91 allocVarsL (LenS len) v = VarS (allocVarsL len v)
93 allocVarsR len VarZ{..} = VarZ{varZNext = addLen varZNext len, ..}
94 allocVarsR len (VarS v) = VarS (allocVarsR len v)
99 xVar meta xVS (x :: xK) ->
100 yVar meta yVS (y :: yK) ->
101 ( xVar meta (xVS ++ yVS) x
102 , yVar meta (xVS ++ yVS) y
105 ( allocVarsR (lenVar y) x
106 , allocVarsL (lenVar x) y
109 -- ** Type 'IndexVar'
111 -- | Index of a 'Var'.
114 indexVar :: Var meta vs v -> Int
116 indexVar (VarS v) = 1 Prelude.+ indexVar v
118 -- instance KindOf (Var meta vs) where
121 -- go :: forall vs2 aK a. Var meta vs2 (Proxy (a::aK)) -> TypeRep aK
122 -- go VarZ{varKind} = varKind
123 -- go (VarS v) = go v
126 type Vars meta vs = Map.Map Name (VarV meta vs)
128 lookupVar :: Name -> Vars meta vs -> Maybe (VarV meta vs)
129 lookupVar = Map.lookup
131 insertVar :: Name -> VarV meta vs -> Vars meta vs -> Vars meta vs
132 insertVar = Map.insert
136 -- | List of 'Var's, used to change the context of a 'Var'
137 -- when removing unused 'Var's.
138 data UsedVars oldVS meta newVS a where
139 UsedVarsZ :: UsedVars oldVS meta '[] a
141 Var meta oldVS (v :: vK) ->
142 UsedVars oldVS meta newVS a ->
143 UsedVars oldVS meta (Proxy (v :: vK) ': newVS) a
145 instance LenVar (UsedVars oldVS) where
146 lenVar UsedVarsZ = LenZ
147 lenVar (UsedVarsS _v oldVS) = LenS $ lenVar oldVS
150 Var meta oldVS (v :: vK) ->
151 UsedVars oldVS meta newVS a ->
152 Maybe (Var meta newVS (v :: vK))
153 lookupUsedVars _v UsedVarsZ = Nothing
154 lookupUsedVars v (UsedVarsS v' us) = do
158 Var{varKind, varMeta} ->
161 { varZNext = lenVar us
165 Nothing -> VarS Data.Functor.<$> lookupUsedVars v us
169 UsedVars vs meta us a ->
170 Maybe (UsedVars vs meta (Proxy v ': us) a)
171 insertUsedVars v vs =
172 case lookupUsedVars v vs of
174 Nothing -> Just (UsedVarsS v vs)
176 -- * Class 'VarOccursIn'
178 -- | Test whether a given 'Var' occurs within @(t)@.
179 class VarOccursIn (t :: Type -> [Type] -> aK -> Type) where
180 varOccursIn :: Var meta vs v -> t meta vs a -> Bool
182 -- * Class 'UsedVarsOf'
183 class UsedVarsOf t where
185 UsedVars vs meta oldVS a ->
187 (forall newVS. UsedVars vs meta newVS a -> ret) ->
192 -- Use a CUSK, because it's a polymorphically recursive type,
193 -- See https://ryanglscott.github.io/2020/01/05/five-benefits-to-using-standalonekindsignatures/
194 data Ty :: forall aK. Type -> [Type] -> aK -> Type where
195 TyConst :: {tyConst :: Const meta a, tyConstLen :: Len vs} -> Ty meta vs a
196 TyVar :: {tyVar :: Var meta vs a, tyVarName :: Name} -> Ty meta vs a
197 TyApp :: {tyAppFun :: Ty meta vs f, tyAppArg :: Ty meta vs a} -> Ty meta vs (f a)
200 tyOfTypeRep :: meta -> Len vs -> TypeRep a -> Ty meta vs a
201 tyOfTypeRep meta len ty = case ty of
202 App f x -> TyApp{tyAppFun = tyOfTypeRep meta len f, tyAppArg = tyOfTypeRep meta len x}
203 constType -> TyConst{tyConst = Const{constType, constMeta = meta}, tyConstLen = len}
205 -- | Monomorphic 'Ty' from a 'Typeable'.
206 monoTy :: forall {aK} (a :: aK) meta. Typeable a => Monoid meta => Ty meta '[] a
207 monoTy = tyOfTypeRep mempty LenZ typeRep
211 forall k (fun :: k) meta vs.
221 , fun ~~ (arg -> res)
223 -- , r2 ~ LiftedRep {- fixme: remove those 2 constraints -}
228 pattern FUN arg res <-
232 { tyAppFun = TyConst{tyConst = Const{constType = eqTypeRep (typeRep @(->)) -> Just HRefl}}
238 (~>) :: Monoid meta => Ty meta vs a -> Ty meta vs b -> Ty meta vs (a -> b)
244 TyConst{tyConst = Const{constType = typeRep, constMeta = mempty}, tyConstLen = (lenVar arg)}
251 deriving instance Show meta => Show (Ty meta vs a)
253 -- type instance SourceOf (Ty vs src t) = src
254 instance LenVar Ty where
255 lenVar TyConst{tyConstLen} = tyConstLen
256 lenVar TyApp{tyAppFun} = lenVar tyAppFun
257 lenVar TyVar{tyVar} = lenVar tyVar
259 -- lenVars (TyFam l _f _as) = l
260 instance AllocVars Ty where
261 allocVarsL len ty@TyConst{..} = ty{tyConstLen = addLen len tyConstLen}
262 allocVarsL len TyApp{..} = TyApp{tyAppFun = allocVarsL len tyAppFun, tyAppArg = allocVarsL len tyAppArg}
263 allocVarsL len ty@TyVar{..} = ty{tyVar = allocVarsL len tyVar}
265 -- allocVarsL len (TyFam l f as) = TyFam (addLen len l) f $ allocVarsL len `mapTys` as
267 allocVarsR len ty@TyConst{..} = ty{tyConstLen = addLen tyConstLen len}
268 allocVarsR len TyApp{..} = TyApp{tyAppFun = allocVarsR len tyAppFun, tyAppArg = allocVarsR len tyAppArg, ..}
269 allocVarsR len ty@TyVar{..} = ty{tyVar = allocVarsR len tyVar}
271 -- allocVarsR len (TyFam l f as) = TyFam (addLen l len) f $ allocVarsR len `mapTys` as
272 instance VarOccursIn Ty where
273 varOccursIn v TyVar{tyVar = v'} | Just{} <- v `eqTy` v' = False
274 varOccursIn _v TyVar{} = False
275 varOccursIn _v TyConst{} = False
276 varOccursIn v TyApp{tyAppFun = f, tyAppArg = a} = varOccursIn v f Prelude.|| varOccursIn v a
278 -- varOccursIn v (TyFam _src _len _fam as) = varOccursIn v as
279 instance UsedVarsOf Ty where
280 usedVarsOf vs TyConst{} k = k vs
281 usedVarsOf vs TyApp{tyAppFun = f, tyAppArg = a} k =
282 usedVarsOf vs f $ \vs' ->
284 usedVarsOf vs TyVar{tyVar = v} k =
285 case insertUsedVars v vs of
289 -- usedVarsOf vs (TyFam _src _len _fam as) k = usedVarsOf vs as k
293 -- | Existential for 'Type'.
294 data TyT meta vs = forall a. TyT (Ty meta vs a)
296 -- type instance SourceOf (TyT vs src) = src
297 instance Eq (TyT meta vs) where
298 TyT x == TyT y = isJust $ eqTy x y
299 instance Show meta => Show (TyT meta vs) where
300 showsPrec p (TyT x) = showsPrec p x
303 type Kind meta a = Ty meta '[] a
306 type KindK meta = TyT meta '[]
309 data TyVT meta = forall vs a. TyVT (Ty meta vs a)
311 deriving instance Show meta => Show (TyVT meta)
312 instance Eq (TyVT m) where
313 TyVT x == TyVT y = isJust (eqTy x' y')
315 (x', y') = appendVars x y
317 -- instance (Monoid src) => EqTy (MT.Writer src) (MT.Writer src) where
318 -- eqTy x y = eqTy (unSourced x) (unSourced y)
319 instance EqTy (Ty meta vs) (Ty meta vs) where
322 go :: forall xK xT yK yT. Ty meta vs (xT :: xK) -> Ty meta vs (yT :: yK) -> Maybe (xT :~~: yT)
323 go TyConst{tyConst = x} TyConst{tyConst = y} = eqTy x y
324 go TyVar{tyVar = x} TyVar{tyVar = y} = eqTy x y
325 go TyApp{tyAppFun = xF, tyAppArg = xA} TyApp{tyAppFun = yF, tyAppArg = yA}
326 | Just HRefl <- go xF yF
327 , Just HRefl <- go xA yA =
331 -- eqTy (TyFam _ _lx xF xA) (TyFam _ _ly yF yA)
332 -- | Just HRefl <- eqTypeRep xF yF
333 -- , Just HRefl <- eqTys xA yA
335 -- -- NOTE: 'TyFam' is expanded as much as possible.
336 -- eqTy x@TyFam{} y = eqTy (expandFam x) y
337 -- eqTy x y@TyFam{} = eqTy x (expandFam y)
340 data Tys (as :: [Type]) meta vs (a :: aK) where
341 TysZ :: Tys '[] meta vs a
342 TysS :: Ty meta vs a -> Tys as meta vs b -> Tys (Proxy a ': as) meta vs b
345 -- type instance SourceOf (Tys vs src ts) = src
346 -- instance ConstsOf (Tys meta vs ts) where
347 -- constsOf TysZ = Set.empty
348 -- constsOf (TysS t ts) = constsOf t `Set.union` constsOf ts
349 instance UsedVarsOf (Tys as) where
350 usedVarsOf vs TysZ k = k vs
351 usedVarsOf vs (TysS t ts) k =
352 usedVarsOf vs t $ \vs' ->
354 instance VarOccursIn (Tys as) where
355 varOccursIn _v TysZ = False
356 varOccursIn v (TysS t ts) = varOccursIn v t Prelude.|| varOccursIn v ts
358 -- ** Type family 'FunArg'
359 type family FunArg (fun :: Type) :: Type where
360 FunArg (q #> f) = FunArg f
363 -- ** Type family 'FunRes'
364 type family FunRes (fun :: Type) :: Type where
365 FunRes (q #> f) = FunRes f
368 -- -- | Return, when the given 'Type' is a function,
369 -- -- the argument of that function.
372 -- SourceInj (TyVT src) src =>
373 -- --Constable (->) =>
375 -- Maybe ( Type src tys (FunArg t)
376 -- , Type src tys (FunRes t) )
377 -- unTyFun ty_ini = go ty_ini
381 -- Maybe ( Type src tys (FunArg x)
382 -- , Type src tys (FunRes x) )
383 -- go (TyApp _ (TyApp _ (TyConst _ _ f) a) b)
384 -- | Just HRefl <- proj_ConstKi @(K (->)) @(->) f
385 -- = Just ((a `withSource` TyVT ty_ini), (b `withSource` TyVT ty_ini))
386 -- go (TyApp _ (TyApp _ (TyConst _ _ f) _a) b)
387 -- | Just HRefl <- proj_ConstKi @(K (#>)) @(#>) f
389 -- go TyApp{} = Nothing
390 -- go TyConst{} = Nothing
391 -- go TyVar{} = Nothing
392 -- go TyFam{} = Nothing
395 forall kc (c :: kc) u meta.
397 -- (kc ~ Type_of_Ty (Ty_of_Type kc)) =>
398 -- KindInjP (Ty_of_Type kc) =>
401 proj_ConstKi = eqTypeRep (typeRep @c) . constType
405 -- | /Type constant/ to qualify a 'Type'.
406 newtype (#>) (q :: Constraint) (a :: Type) = Qual (q => a)
408 -- | Qualify a 'Type'.
409 (#>) :: Monoid meta => Ty meta vs q -> Ty meta vs t -> Ty meta vs (q #> t)
411 -- (tyConstLen @(K (#>)) @(#>) (lenVars q) `tyApp` q) `tyApp` t
415 { tyAppFun = TyConst{tyConst = Const{constType = typeRep @(#>), constMeta = mempty}, tyConstLen = lenVar q}
423 -- NOTE: should actually be (-1)
424 -- to compose well with @infixr 0 (->)@
425 -- but this is not allowed by GHC.
429 -- | 'Constraint' union.
430 class ((x, y) :: Constraint) => x # y
432 instance ((x, y) :: Constraint) => x # y
434 -- | Unify two 'K.Constraint's.
435 (#) :: Monoid meta => Ty meta vs qx -> Ty meta vs qy -> Ty meta vs (qx # qy)
437 -- (tyConstLen @(K (#)) @(#) (lenVars a) `tyApp` a) `tyApp` b
441 { tyAppFun = TyConst{tyConst = Const{constType = typeRep @(#), constMeta = mempty}, tyConstLen = lenVar a}
450 class KindOf (ty :: Type -> [Type] -> aK -> Type) where
451 -- | Return the kind of the given 'Var'.
455 ty meta vs (a :: aK) ->
456 Kind meta (aK :: Type)
458 instance KindOf Var where
459 kindOf Var{varKind} = varKind
460 instance KindOf Ty where
461 kindOf TyConst{tyConst = Const{..} :: Const meta (a :: aK)} =
462 tyOfTypeRep constMeta LenZ (typeRepKind constType)
463 kindOf TyApp{tyAppFun = f} = case kindOf f of
467 { tyAppFun = TyConst{tyConst = Const{constType = eqTypeRep (typeRep @(->)) -> Just HRefl}}
471 t -> error $ "here: " <> show t
472 kindOf TyVar{tyVar = Var{varKind, varMeta}} = varKind
474 -- kindOf (TyFam _src _len fam _as) = kindOfConst fam