1 {-# LANGUAGE ConstraintKinds #-}
3 {-# LANGUAGE PolyKinds #-}
4 {-# LANGUAGE UndecidableInstances #-}
5 {-# OPTIONS_GHC -fno-warn-orphans #-}
6 module Language.Symantic.Compiling.Term
7 ( module Language.Symantic.Compiling.Term
8 , module Language.Symantic.Compiling.Term.Grammar
11 import Data.Proxy (Proxy(..))
12 import qualified Data.Text as Text
13 import Data.Type.Equality ((:~:)(..))
14 import GHC.Exts (Constraint)
16 import Language.Symantic.Helper.Data.Type.List
17 import Language.Symantic.Parsing
18 import Language.Symantic.Typing
20 import Language.Symantic.Compiling.Term.Grammar
23 -- | An open term (i.e. depending on a 'TeCtx').
24 -- The data type wraps a universal quantification
25 -- over an interpreter @term@
26 -- qualified by the symantics of a term.
28 -- Moreover the term is abstracted by a /lambda term context/
29 -- built top-down by 'compile',
30 -- to enable a /Higher-Order Abstract Syntax/ (HOAS)
31 -- for /lambda abstractions/ ('lam').
33 -- This data type is used to keep a parsed term polymorphic enough
34 -- to stay interpretable by different interpreters.
36 -- * @(@'Sym_of_Ifaces'@ is term)@
37 -- is needed when a symantic method includes a polymorphic type
38 -- and thus calls: 'compile'.
40 -- * @(@'Sym_of_Ifaces'@ ls term)@ and @(@'Sym_of_Ifaces'@ rs term)@
41 -- make a zipper needed to be able to write the recursing 'CompileR' instance.
43 -- * @(@'Sym_of_Iface'@ (@'Proxy'@ (->)) term)@
44 -- is needed to handle partially applied functions.
45 data Term hs h is ls rs
47 (forall term. ( Sym_of_Ifaces is term
48 , Sym_of_Ifaces ls term
49 , Sym_of_Ifaces rs term
50 , Sym_of_Iface (Proxy (->)) term
51 ) => TeCtx term hs -> term h)
54 -- | Existential 'Term', with its 'Type'.
56 = forall (h:: *). ETerm (Type cs h) (Term hs h is '[] is)
58 -- ** Type 'TermClosed'
62 (forall term. ( Sym_of_Ifaces is term
63 , Sym_of_Iface (Proxy (->)) term
66 -- * Type 'ETermClosed'
67 -- | Existential 'TermClosed', with its 'Type'.
68 data ETermClosed cs is
69 = forall (h:: *). ETermClosed (Type cs h) (TermClosed is h)
72 -- | Convenient class wrapping 'CompileR' to initiate its recursion.
73 class CompileR cs is '[] is => Compile cs is where
74 compile :: EToken meta is -> Compiler meta hs ret cs is '[] is
75 instance CompileR cs is '[] is => Compile cs is where
76 compile (EToken tok) = compileR tok
78 -- ** Type 'CompilerWithTyCtx'
79 -- | Convenient type synonym defining a term compiler
80 -- with independant 'TyCtx' and 'TeCtx'.
82 -- This is the most general term compiler.
84 -- Useful to let the compiled term use
85 -- terms whose type is known before 'compile' is run
86 -- but actually available only after.
87 type CompilerWithTyCtx meta hs_ty hs_te ret cs is ls rs
88 = TyCtx TeName cs hs_ty
89 -- ^ The bound variables in scope and their types:
90 -- built top-down in the heterogeneous list @hs@,
91 -- from the closest including /lambda abstraction/ to the farest.
94 -> Term hs_te h is ls rs
95 -> Either (Error_Term meta cs is) ret )
96 -- ^ The accumulating continuation, called bottom-up.
97 -> Either (Error_Term meta cs is) ret
99 -- | Like 'compile' but also enables the use of a 'TyCtx'
100 -- whose actual terms are only known after 'compile' has been run.
101 -- This also enables to 'compile' a term once
102 -- and interpret it with different 'TeCtx's,
103 -- providing the types of those terms match the given 'TyCtx'.
107 -> TyCtx TeName cs hs_ty
108 -> Either (Error_Term meta cs is) (ETerm hs_ty cs is)
109 compileWithTyCtx tok ctx =
110 compile tok ctx $ \typ -> Right . ETerm typ
112 -- | Return given 'Compiler' augmented with given 'TyCtx'.
115 => TyCtx TeName cs hs_ty
116 -> (forall hs. Compiler meta hs ret cs is ls rs)
117 -> CompilerWithTyCtx meta hs_te (hs_ty ++ hs_te) ret cs is ls rs
118 compilerWithTyCtx tyCtx comp ctx =
119 comp (appendTyCtx tyCtx ctx)
121 -- | Compile, closing the 'TyCtx'.
122 compilerWithTyCtx_close
123 :: CompilerWithTyCtx meta '[] hs_te (ETerm hs_te cs is) cs is '[] is
124 -> Either (Error_Term meta cs is) (ETerm hs_te cs is)
125 compilerWithTyCtx_close comp =
126 comp TyCtxZ $ \typ -> Right . ETerm typ
128 -- ** Type 'Compiler'
129 -- | Convenient type synonym defining a term compiler.
130 -- with matching 'TyCtx' and 'TeCtx'.
132 -- Useful to let the compiled term use
133 -- terms known before 'compile' is run.
134 type Compiler meta hs ret cs is ls rs
135 = CompilerWithTyCtx meta hs hs ret cs is ls rs
137 -- | Compile with an empty /lambda context/.
141 -> Either (Error_Term meta cs is) (ETermClosed cs is)
142 compileWithoutCtx tok = compilerWithCtx_close (compile tok)
144 -- ** Type 'ACompileWithCtx'
145 -- | Wrap 'Compiler' to keep the /lambda context/ fully polymorphic.
147 -- Useful in 'compilerWithCtx' to help GHC's type solver, which
148 -- "Cannot instantiate unification variable with a type involving foralls".
149 data ACompileWithCtx meta ret cs is ls rs
151 { unACompileWithCtx :: forall hs. Compiler meta hs ret cs is ls rs }
153 -- | Compile with given /lambda context/.
156 => f (TeName, ETermClosed cs is)
157 -> (forall hs'. Compiler meta hs' ret cs is ls rs)
158 -> Compiler meta hs ret cs is ls rs
159 compilerWithCtx env comp = unACompileWithCtx $
161 (\e (ACompileWithCtx c) -> ACompileWithCtx $ compilerWithCtx_push e c)
162 (ACompileWithCtx comp) env
164 -- | Return given 'Compiler' with a /lambda context/ augmented with given 'ETermClosed'.
166 :: (TeName, ETermClosed cs is)
167 -> (forall hs'. Compiler meta hs' ret cs is ls rs)
168 -> Compiler meta hs ret cs is ls rs
169 compilerWithCtx_push (n, ETermClosed ty_n (TermClosed te_n)) comp ctx k =
170 comp (TyCtxS n ty_n ctx) $ \ty_y (Term y) ->
172 \c -> y (te_n `TeCtxS` c)
174 -- | Compile with given 'Compiler', closing the /lambda context/.
175 compilerWithCtx_close
176 :: (forall hs. Compiler meta hs (ETermClosed cs is) cs is '[] is)
177 -> Either (Error_Term meta cs is) (ETermClosed cs is)
178 compilerWithCtx_close comp =
179 comp TyCtxZ $ \typ (Term te) ->
180 Right $ ETermClosed typ $ TermClosed $ te TeCtxZ
182 -- ** Class 'CompileR'
183 -- | Intermediate type class to construct an instance of 'Compile'
184 -- from many instances of 'CompileI', one for each item of @is@.
186 -- * @is@: starting list of /term constants/.
187 -- * @ls@: done list of /term constants/.
188 -- * @rs@: remaining list of /term constants/.
189 class CompileR (cs::[*]) (is::[*]) (ls::[*]) (rs::[*]) where
190 compileR :: TokenR meta is rs i -> Compiler meta hs ret cs is ls rs
192 -- | Recurse into into the given 'TokenR'
193 -- to call the 'compileI' instance associated
194 -- to the 'TokenT' it contains.
197 , CompileR cs is (i ': ls) (r ': rs)
198 ) => CompileR cs is ls (i ': r ': rs) where
201 TokenZ _m t -> compileI t ctx k
203 compileR t ctx $ \typ (Term te :: Term hs h is (i ': ls) (r ': rs)) ->
204 k typ (Term te :: Term hs h is ls (i ': r ': rs))
205 -- | End the recursion.
208 CompileR cs is ls (i ': '[]) where
209 compileR (TokenZ _m t) ctx k = compileI t ctx k
210 compileR TokenS{} _ctx _k = error "Oops, the impossible happened..."
212 -- ** Class 'CompileI'
213 -- | Handle the work of 'Compile' for a given /interface/ @i@.
214 class CompileI (cs::[*]) (is::[*]) (i:: *) where
215 compileI :: TokenT meta is i -> Compiler meta hs ret cs is ls (i ': rs)
217 -- * Type family 'Sym_of_Ifaces'
218 type family Sym_of_Ifaces (is::[*]) (term:: * -> *) :: Constraint where
219 Sym_of_Ifaces '[] term = ()
220 Sym_of_Ifaces (i ': is) term = (Sym_of_Iface i term, Sym_of_Ifaces is term)
222 -- ** Type family 'Sym_of_Iface'
223 type family Sym_of_Iface (i:: *) :: {-term-}(* -> *) -> Constraint
225 -- * Type 'TyConsts_of_Ifaces'
226 type TyConsts_of_Ifaces is = Nub (TyConsts_of_IfacesR is)
228 -- ** Type family 'TyConsts_of_IfacesR'
229 type family TyConsts_of_IfacesR (is::[*]) where
230 TyConsts_of_IfacesR '[] = '[]
231 TyConsts_of_IfacesR (i ': is) = TyConsts_of_Iface i ++ TyConsts_of_IfacesR is
233 {- NOTE: failed attempt to recursively collect TyConsts.
234 -- ** Type family 'TyConsts_imported_byR'
235 type family TyConsts_imported_byR (done::[*]) (cs::[*]) where
236 TyConsts_imported_byR done '[] = done
237 TyConsts_imported_byR done (c ': cs) =
239 (TyConsts_imported_byR done cs)
240 (TyConsts_imported_byR (c ': done) (TyConsts_imported_by c ++ TyConsts_imported_byR done cs))
243 -- ** Type family 'TyConsts_of_Iface'
244 type family TyConsts_of_Iface (i:: *) :: [*]
246 -- ** Type family 'TyConsts_imported_by'
247 -- | Return the /type constant/s that a given /type constant/
248 -- wants to be part of the final list of /type constants/.
249 type family TyConsts_imported_by (c:: *) :: [*]
252 -- | GADT for a /typing context/:
253 -- accumulating at each /lambda abstraction/
254 -- the 'Type' of the introduced variable.
255 data TyCtx (name:: *) (cs::[*]) (hs::[*]) where
256 TyCtxZ :: TyCtx name cs '[]
260 -> TyCtx name cs (h ': hs)
264 :: TyCtx TeName cs hs0
265 -> TyCtx TeName cs hs1
266 -> TyCtx TeName cs (hs0 ++ hs1)
267 appendTyCtx TyCtxZ c = c
268 appendTyCtx (TyCtxS n t c) c' = TyCtxS n t $ appendTyCtx c c'
271 -- | GADT for an /interpreting context/:
272 -- accumulating at each /lambda abstraction/
273 -- the @term@ of the introduced variable.
274 data TeCtx (term:: * -> *) (hs::[*]) where
275 TeCtxZ :: TeCtx term '[]
278 -> TeCtx term (h ': hs)
281 -- * Type 'Error_Term'
282 data Error_Term meta (cs::[*]) (is::[*])
283 = Error_Term_unbound TeName
284 | Error_Term_Typing (Error_Type meta '[Proxy Token_Type])
285 | Error_Term_Con_Type
287 (Con_Type meta cs '[Proxy Token_Type])
288 (Con_Type meta cs is))
289 | Error_Term_Con_Kind (Con_Kind meta is)
290 deriving instance (Eq meta, Eq_Token meta is) => Eq (Error_Term meta cs is)
291 deriving instance (Show meta, Show_Token meta is, Show_TyConst cs) => Show (Error_Term meta cs is)
294 data Con_Type meta cs ts
295 = Con_TyEq (Either (At meta '[Proxy Token_Type] (EType cs))
296 (At meta ts (EType cs)))
297 (At meta ts (EType cs))
298 | Con_TyApp (At meta ts (EType cs))
299 | Con_TyCon (At meta ts (KType cs Constraint))
300 | Con_TyFam (At meta ts TyFamName) [EType cs]
304 ) => Eq (Con_Type meta cs ts)
309 ) => Show (Con_Type meta cs ts)
311 instance MonoLift (Error_Type meta '[Proxy Token_Type]) (Error_Term meta cs ts) where
312 olift = Error_Term_Typing . olift
313 instance MonoLift (Error_Term meta cs ts) (Error_Term meta cs ts) where
316 MonoLift (Con_Type meta cs is) (Error_Term meta cs is) where
317 olift = Error_Term_Con_Type . Right
319 MonoLift (Con_Type meta cs '[Proxy Token_Type]) (Error_Term meta cs is) where
320 olift = Error_Term_Con_Type . Left
321 instance MonoLift (Con_Kind meta '[Proxy Token_Type]) (Error_Term meta cs is) where
322 olift = Error_Term_Typing . Error_Type_Con_Kind
323 instance MonoLift (Con_Kind meta is) (Error_Term meta cs is) where
324 olift = Error_Term_Con_Kind
328 :: MonoLift (Con_Type meta cs ts) err
329 => At meta ts (Type cs x)
330 -> At meta ts (Type cs y)
331 -> ((x :~: y) -> Either err ret) -> Either err ret
333 case unAt x `eq_Type` unAt y of
335 Nothing -> Left $ olift $
336 Con_TyEq (Right $ EType <$> x) (EType <$> y)
339 :: MonoLift (Con_Type meta cs ts) err
340 => At meta '[Proxy Token_Type] (Type cs x)
341 -> At meta ts (Type cs y)
342 -> ((x :~: y) -> Either err ret) -> Either err ret
343 check_Type_is x y k =
344 case unAt x `eq_Type` unAt y of
346 Nothing -> Left $ olift $
347 Con_TyEq (Left $ EType <$> x) (EType <$> y)
350 :: MonoLift (Con_Type meta cs ts) err
351 => At meta ts (Type cs (fa::kfa))
352 -> (forall ka f a. (fa :~: f a)
353 -> Type cs (f::ka -> kfa)
361 Con_TyApp (EType <$> typ)
364 :: ( MonoLift (Con_Type meta cs ts) err
365 , MonoLift (Con_Kind meta ts) err )
366 => Type cs (f:: * -> *)
367 -> At meta ts (Type cs fa)
368 -> (forall a. (fa :~: f a)
372 check_TyEq1 typ ty_fa k =
373 check_TyApp ty_fa $ \Refl ty_f ty_a ->
375 (At Nothing $ SKiType `SKiArrow` SKiType)
376 (kind_of ty_f <$ ty_fa) $ \Refl ->
379 (ty_f <$ ty_fa) $ \Refl ->
383 :: ( MonoLift (Con_Type meta cs ts) err
384 , MonoLift (Con_Kind meta ts) err )
385 => Type cs (f:: * -> * -> *)
386 -> At meta ts (Type cs fab)
387 -> (forall a b. (fab :~: f a b)
392 check_TyEq2 typ ty_fab k =
393 check_TyApp ty_fab $ \Refl ty_fa ty_b ->
394 check_TyApp (ty_fa <$ ty_fab) $ \Refl ty_f ty_a ->
396 (At Nothing $ SKiType `SKiArrow` SKiType `SKiArrow` SKiType)
397 (kind_of ty_f <$ ty_fab) $ \Refl ->
400 (ty_f <$ ty_fab) $ \Refl ->
405 , MonoLift (Con_Type meta cs ts) err )
406 => At meta ts (Type cs (q::Constraint))
407 -> (TyCon q -> Either err ret)
410 case proj_TyCon $ unAt typ of
411 Just TyCon -> k TyCon
412 Nothing -> Left $ olift $
413 Con_TyCon (KType <$> typ)
417 , MonoLift (Con_Type meta cs ts) err
418 , MonoLift (Con_Kind meta ts) err )
420 -> At meta ts (Type cs (fa:: *))
421 -> (forall f a. (fa :~: f a)
423 -> Type cs (f:: * -> *)
427 check_TyCon1 con ty_fa k =
428 check_TyApp ty_fa $ \Refl ty_f ty_a ->
430 (At Nothing (SKiType `SKiArrow` SKiType))
431 (kind_of ty_f <$ ty_fa) $ \Refl ->
432 check_TyCon ((con :$ ty_f) <$ ty_fa) $ \TyCon ->
433 k Refl TyCon ty_f ty_a
436 :: ( MonoLift (Con_Type meta cs ts) err
441 -> (Type cs (TyFam fam hs) -> Either err ret)
443 check_TyFam fam tys k =
444 case proj_TyFam (unAt fam) tys of
446 Nothing -> Left $ olift $
448 (Text.pack . show <$> fam)