]> Git — Sourcephile - haskell/symantic.git/blob - Language/LOL/Symantic/Expr/Common.hs
init
[haskell/symantic.git] / Language / LOL / Symantic / Expr / Common.hs
1 {-# LANGUAGE ConstraintKinds #-}
2 {-# LANGUAGE DataKinds #-}
3 {-# LANGUAGE FlexibleContexts #-}
4 {-# LANGUAGE FlexibleInstances #-}
5 {-# LANGUAGE GADTs #-}
6 {-# LANGUAGE KindSignatures #-}
7 {-# LANGUAGE MultiParamTypeClasses #-}
8 {-# LANGUAGE Rank2Types #-}
9 {-# LANGUAGE ScopedTypeVariables #-}
10 {-# LANGUAGE TypeFamilies #-}
11 {-# LANGUAGE TypeOperators #-}
12 {-# LANGUAGE UndecidableInstances #-}
13 module Language.LOL.Symantic.Expr.Common where
14
15 import Data.Proxy (Proxy(..))
16 import GHC.Prim (Constraint)
17 import Data.Text (Text)
18 import Data.Peano
19
20 import Language.LOL.Symantic.AST
21 import Language.LOL.Symantic.Type
22
23 -- * Class 'Expr_from'
24
25 class Expr_from ast (ex:: *) where
26 expr_from
27 :: forall hs ret
28 . Proxy ex
29 -- ^ Select the 'Expr_from' instance for the expression @ex@.
30 -> Context (Var (Type_Root_of_Expr ex)) hs
31 -- ^ The bound variables in scope and their types:
32 -- held in the heterogeneous list @hs@,
33 -- from the closest including lambda abstraction to the farest.
34 -> ast
35 -- ^ The input data to parse.
36 -> ( forall h
37 . Type_Root_of_Expr ex h
38 -> Forall_Repr_with_Context ex hs h
39 -> Either (Error_of_Expr ast (Root_of_Expr ex)) ret )
40 -- ^ The accumulating continuation.
41 -> Either (Error_of_Expr ast (Root_of_Expr ex)) ret
42
43 -- ** Type 'Context'
44
45 -- | GADT for a typing context,
46 -- accumulating an @item@ at each lambda;
47 -- used to accumulate object-types of lambda variables in 'Expr_from'
48 -- or host-terms of lambda variables in 'Repr_Host'.
49 data Context :: (* -> *) -> [*] -> * where
50 Context_Empty :: Context item '[]
51 Context_Alt_Next :: item h -> Context item hs -> Context item (h ': hs)
52 infixr 5 `Context_Alt_Next`
53
54 -- ** Type 'Var'
55 -- | Join a name and a type.
56 --
57 -- This data type is used to handle lambda variables by name
58 -- (instead of DeBruijn indices for instance).
59 data Var ty h
60 = Var Var_Name (ty h)
61 type Var_Name = Text
62
63 -- ** Type 'Forall_Repr_with_Context'
64 -- | A data type embedding a universal quantification
65 -- over an interpreter @repr@
66 -- and qualified by the symantics of an expression.
67 --
68 -- Moreover the expression is abstracted by a 'Context'
69 -- built at parsing time to build a /Higher-Order Abstract Syntax/ (HOAS)
70 -- for lambda abstractions.
71 --
72 -- This data type is used to keep a parsed expression polymorphic enough
73 -- to stay interpretable by different interpreters.
74 --
75 -- NOTE: 'Sym_of_Expr'@ ex repr@
76 -- is needed to be able to use symantic methods of the parsed expression
77 -- into a 'Forall_Repr_with_Context' @ex@.
78 --
79 -- NOTE: 'Sym_of_Expr'@ (@'Root_of_Expr'@ ex) repr@
80 -- is needed to be able to use an expression
81 -- out of a 'Forall_Repr_with_Context'@ (@'Root_of_Expr'@ ex)@
82 -- into a 'Forall_Repr_with_Context'@ ex@,
83 -- which happens when a symantic method includes a polymorphic type
84 -- and thus calls: 'expr_from'@ (Proxy::Proxy (@'Root_of_Expr'@ ex))@.
85 data Forall_Repr_with_Context ex hs h
86 = Forall_Repr_with_Context
87 ( forall repr. ( Sym_of_Expr ex repr
88 , Sym_of_Expr (Root_of_Expr ex) repr
89 ) => Context repr hs -> repr h )
90
91 -- ** Type 'Forall_Repr'
92 data Forall_Repr ex h
93 = Forall_Repr
94 { unForall_Repr :: forall repr
95 . Sym_of_Expr ex repr
96 => repr h }
97
98 -- ** Type family 'Root_of_Expr'
99 -- | The root expression, closing an expression with itself.
100 type family Root_of_Expr (ex:: *) :: *
101
102 -- ** Type family 'Sym_of_Expr'
103 -- | The symantic of an expression.
104 type family Sym_of_Expr (ex:: *) (repr:: * -> *) :: Constraint
105
106 -- ** Type family 'Error_of_Expr'
107 -- | The error(s) of an expression.
108 type family Error_of_Expr (ast:: *) (ex:: *) :: *
109
110 -- ** Type family 'Type_of_Expr'
111 -- | The type of an expression, parameterized by a root type.
112 type family Type_of_Expr (ex:: *) :: {-root-}(* -> *) -> {-h-}* -> *
113
114 -- ** Type 'Type_Root_of_Expr'
115 -- | Convenient alias.
116 type Type_Root_of_Expr ex
117 = Type_Root (Type_of_Expr (Root_of_Expr ex))
118
119 -- * Type 'Expr_Root'
120 -- | The root expression, passing itself as parameter to the given expression.
121 newtype Expr_Root (ex:: * -> *)
122 = Expr_Root (ex (Expr_Root ex))
123 type instance Root_of_Expr (Expr_Root ex) = Expr_Root ex
124 type instance Type_of_Expr (Expr_Root ex)
125 = Type_of_Expr (ex (Expr_Root ex))
126 -- NOTE: require UndecidableInstances.
127 type instance Error_of_Expr ast (Expr_Root ex)
128 = Error_Expr_Alt (Error_Expr (Error_of_Type ast (Type_Root_of_Expr (ex (Expr_Root ex))))
129 (Type_Root_of_Expr (ex (Expr_Root ex)))
130 ast)
131 (Error_of_Expr ast (ex (Expr_Root ex)))
132 -- NOTE: require UndecidableInstances.
133 type instance Sym_of_Expr (Expr_Root ex) repr
134 = Sym_of_Expr (ex (Expr_Root ex)) repr
135 -- NOTE: require UndecidableInstances.
136 instance -- Expr_from
137 ( Expr_from ast (ex (Expr_Root ex))
138 , Root_of_Expr (ex (Expr_Root ex)) ~ Expr_Root ex
139 ) => Expr_from ast (Expr_Root ex) where
140 expr_from _px_ex ctx ast k =
141 expr_from (Proxy::Proxy (ex (Expr_Root ex)))
142 ctx ast $ \ty (Forall_Repr_with_Context repr) ->
143 k ty (Forall_Repr_with_Context repr)
144
145 {- NOTE: useless code so far.
146 -- ** Class 'Expr_Root_Lift'
147 -- | Lift a given expression to a given root expression.
148 class Expr_Root_Lift ex root where
149 expr_root_lift :: ex root -> root
150 instance
151 Expr_Lift ex root =>
152 Expr_Root_Lift ex (Expr_Root root) where
153 expr_root_lift = Expr_Root . expr_lift
154 -}
155
156 -- * Type 'Expr_Alt'
157 -- | Expression making an alternative between two expressions.
158 data Expr_Alt curr next (root:: *)
159 = Expr_Alt_Curr (curr root)
160 | Expr_Alt_Next (next root)
161 type instance Root_of_Expr (Expr_Alt curr next root) = root
162 type instance Type_of_Expr (Expr_Alt curr next root)
163 = Type_Alt (Type_of_Expr (curr root))
164 (Type_of_Expr (next root))
165 type instance Error_of_Expr ast (Expr_Alt curr next root)
166 = Error_Expr_Alt (Error_of_Expr ast (curr root))
167 (Error_of_Expr ast (next root))
168 type instance Sym_of_Expr (Expr_Alt curr next root) repr
169 = ( Sym_of_Expr (curr root) repr
170 , Sym_of_Expr (next root) repr
171 )
172 instance -- Expr_from
173 ( Expr_from ast (curr root)
174 , Expr_from ast (next root)
175 , Root_of_Expr (curr root) ~ root
176 , Root_of_Expr (next root) ~ root
177 , Error_Expr_Unlift (Error_Expr (Error_of_Type ast (Type_Root_of_Expr root))
178 (Type_Root_of_Expr root) ast)
179 (Error_of_Expr ast root)
180 ) => Expr_from ast (Expr_Alt curr next root) where
181 expr_from _px_ex ctx ast k =
182 case expr_from (Proxy::Proxy (curr root)) ctx ast $
183 \ty (Forall_Repr_with_Context repr) ->
184 Right $ k ty (Forall_Repr_with_Context repr) of
185 Right ret -> ret
186 Left err ->
187 case error_expr_unlift err of
188 Just (Error_Expr_Unsupported_here _
189 :: Error_Expr (Error_of_Type ast (Type_Root_of_Expr root))
190 (Type_Root_of_Expr root) ast) ->
191 expr_from (Proxy::Proxy (next root)) ctx ast $
192 \ty (Forall_Repr_with_Context repr) ->
193 k ty (Forall_Repr_with_Context repr)
194 _ -> Left err
195
196 {- NOTE: useless code so far.
197 -- ** Type 'Expr_Lift'
198 -- | Apply 'Peano_of_Expr' on 'Expr_LiftN'.
199 type Expr_Lift ex exs
200 = Expr_LiftN (Peano_of_Expr ex exs) ex exs
201
202 -- | Convenient wrapper around 'expr_liftN',
203 -- passing it the 'Peano' number from 'Peano_of_Expr'.
204 expr_lift
205 :: forall ex exs (root:: *).
206 Expr_Lift ex exs =>
207 ex root -> exs root
208 expr_lift = expr_liftN (Proxy::Proxy (Peano_of_Expr ex exs))
209
210 -- *** Type family 'Peano_of_Expr'
211 -- | Return a 'Peano' number derived from the location
212 -- of a given expression within a given expression stack,
213 -- which is used to avoid @OverlappingInstances@.
214 type family Peano_of_Expr
215 (ex:: * -> *)
216 (exs:: * -> *) :: Peano where
217 Peano_of_Expr ex ex = 'Zero
218 Peano_of_Expr ex (Expr_Alt ex next) = 'Zero
219 Peano_of_Expr other (Expr_Alt curr next) = 'Succ (Peano_of_Expr other next)
220
221 -- *** Class 'Expr_LiftN'
222 -- | Lift a given expression to the top of a given expression stack including it,
223 -- by constructing the appropriate sequence of 'Expr_Alt_Curr' and 'Expr_Alt_Next'.
224 class Expr_LiftN (n::Peano) ex exs where
225 expr_liftN :: forall (root:: *). Proxy n -> ex root -> exs root
226 instance Expr_LiftN 'Zero curr curr where
227 expr_liftN _ = id
228 instance Expr_LiftN 'Zero curr (Expr_Alt curr next) where
229 expr_liftN _ = Expr_Alt_Curr
230 instance
231 Expr_LiftN n other next =>
232 Expr_LiftN ('Succ n) other (Expr_Alt curr next) where
233 expr_liftN _ = Expr_Alt_Next . expr_liftN (Proxy::Proxy n)
234 -}
235
236 {- NOTE: useless code so far.
237 -- ** Type 'Expr_Unlift'
238 -- | Apply 'Peano_of_Expr' on 'Expr_UnliftN'.
239 type Expr_Unlift ex exs
240 = Expr_UnliftN (Peano_of_Expr ex exs) ex exs
241
242 -- | Convenient wrapper around 'expr_unliftN',
243 -- passing it the 'Peano' number from 'Peano_of_Expr'.
244 expr_unlift
245 :: forall ex exs (root:: *).
246 Expr_Unlift ex exs =>
247 exs root -> Maybe (ex root)
248 expr_unlift = expr_unliftN (Proxy::Proxy (Peano_of_Expr ex exs))
249
250 -- *** Class 'Expr_UnliftN'
251 -- | Try to unlift a given expression out of a given expression stack including it,
252 -- by deconstructing the appropriate sequence of 'Expr_Alt_Curr' and 'Expr_Alt_Next'.
253 class Expr_UnliftN (n::Peano) ex exs where
254 expr_unliftN :: forall (root:: *). Proxy n -> exs root -> Maybe (ex root)
255 instance Expr_UnliftN 'Zero curr curr where
256 expr_unliftN _ = Just
257 instance Expr_UnliftN 'Zero curr (Expr_Alt curr next) where
258 expr_unliftN _ (Expr_Alt_Curr x) = Just x
259 expr_unliftN _ (Expr_Alt_Next _) = Nothing
260 instance
261 Expr_UnliftN n other next =>
262 Expr_UnliftN ('Succ n) other (Expr_Alt curr next) where
263 expr_unliftN _ (Expr_Alt_Next x) = expr_unliftN (Proxy::Proxy n) x
264 expr_unliftN _ (Expr_Alt_Curr _) = Nothing
265 -}
266
267 -- * Type family 'Is_Last_Expr'
268 -- | Return whether a given expression is the last one in a given expression stack.
269 --
270 -- NOTE: each expression parser uses this type family
271 -- when it encounters unsupported syntax:
272 -- to know if it is the last expression parser component that will be tried
273 -- (and thus return 'Error_Expr_Unsupported')
274 -- or if some other expression parser component shall be tried
275 -- (and thus return 'Error_Expr_Unsupported_here',
276 -- which is then handled accordingly by the 'Expr_from' instance of 'Expr_Alt').
277 type family Is_Last_Expr (ex:: *) (exs:: *) :: Bool where
278 Is_Last_Expr ex ex = 'True
279 Is_Last_Expr ex (Expr_Root exs) = Is_Last_Expr ex (exs (Expr_Root exs))
280 Is_Last_Expr (ex root) (Expr_Alt ex next root) = 'False
281 Is_Last_Expr other (Expr_Alt curr next root) = Is_Last_Expr other (next root)
282
283 -- * Type 'Error_Expr_Alt'
284 -- | Error expression making an alternative between two error expressions.
285 data Error_Expr_Alt curr next
286 = Error_Expr_Alt_Curr curr
287 | Error_Expr_Alt_Next next
288 deriving (Eq, Show)
289
290 -- ** Type 'Error_Expr_Lift'
291 -- | Apply 'Peano_of_Error_Expr' on 'Error_Expr_LiftN'.
292 type Error_Expr_Lift err errs
293 = Error_Expr_LiftN (Peano_of_Error_Expr err errs) err errs
294
295 -- | Convenient wrapper around 'error_expr_liftN',
296 -- passing it the 'Peano' number from 'Peano_of_Error_Expr'.
297 error_expr_lift
298 :: forall err errs.
299 Error_Expr_Lift err errs =>
300 err -> errs
301 error_expr_lift = error_expr_liftN (Proxy::Proxy (Peano_of_Error_Expr err errs))
302
303 -- *** Type family 'Peano_of_Error_Expr'
304 -- | Return a 'Peano' number derived from the location
305 -- of a given error expression within a given error expression stack,
306 -- which is used to avoid @OverlappingInstances@.
307 type family Peano_of_Error_Expr (err:: *) (errs:: *) :: Peano where
308 Peano_of_Error_Expr err err = 'Zero
309 Peano_of_Error_Expr err (Error_Expr_Alt err next) = 'Zero
310 Peano_of_Error_Expr other (Error_Expr_Alt curr next) = 'Succ (Peano_of_Error_Expr other next)
311
312 -- *** Class 'Error_Expr_LiftN'
313 -- | Lift a given expression to the top of a given expression stack including it,
314 -- by constructing the appropriate sequence of 'Error_Expr_Alt_Curr' and 'Error_Expr_Alt_Next'.
315 class Error_Expr_LiftN (n::Peano) err errs where
316 error_expr_liftN :: Proxy n -> err -> errs
317 instance Error_Expr_LiftN 'Zero curr curr where
318 error_expr_liftN _ = id
319 instance Error_Expr_LiftN 'Zero curr (Error_Expr_Alt curr next) where
320 error_expr_liftN _ = Error_Expr_Alt_Curr
321 instance
322 Error_Expr_LiftN n other next =>
323 Error_Expr_LiftN ('Succ n) other (Error_Expr_Alt curr next) where
324 error_expr_liftN _ = Error_Expr_Alt_Next . error_expr_liftN (Proxy::Proxy n)
325
326 -- ** Type 'Error_Expr_Unlift'
327 -- | Apply 'Peano_of_Error_Expr' on 'Error_Expr_UnliftN'.
328 type Error_Expr_Unlift ex exs
329 = Error_Expr_UnliftN (Peano_of_Error_Expr ex exs) ex exs
330
331 -- | Convenient wrapper around 'error_expr_unliftN',
332 -- passing it the 'Peano' number from 'Peano_of_Error_Expr'.
333 error_expr_unlift
334 :: forall ex exs.
335 Error_Expr_Unlift ex exs =>
336 exs -> Maybe ex
337 error_expr_unlift = error_expr_unliftN (Proxy::Proxy (Peano_of_Error_Expr ex exs))
338
339 -- *** Class 'Error_Expr_UnliftN'
340 -- | Try to unlift a given expression error out of a given expression error stack including it,
341 -- by deconstructing the appropriate sequence of 'Error_Expr_Alt_Curr' and 'Error_Expr_Alt_Next'.
342 class Error_Expr_UnliftN (n::Peano) ex exs where
343 error_expr_unliftN :: Proxy n -> exs -> Maybe ex
344 instance Error_Expr_UnliftN 'Zero curr curr where
345 error_expr_unliftN _ = Just
346 instance Error_Expr_UnliftN 'Zero curr (Error_Expr_Alt curr next) where
347 error_expr_unliftN _ (Error_Expr_Alt_Curr x) = Just x
348 error_expr_unliftN _ (Error_Expr_Alt_Next _) = Nothing
349 instance
350 Error_Expr_UnliftN n other next =>
351 Error_Expr_UnliftN ('Succ n) other (Error_Expr_Alt curr next) where
352 error_expr_unliftN _ (Error_Expr_Alt_Next x) = error_expr_unliftN (Proxy::Proxy n) x
353 error_expr_unliftN _ (Error_Expr_Alt_Curr _) = Nothing
354
355 -- ** Type 'Error_Expr_Read'
356 -- | Common expression errors.
357 data Error_Expr err_ty ty ast
358 = Error_Expr_Wrong_number_of_arguments Int ast
359 -- ^ Wrong number of arguments applied to a term,
360 -- the integer is the number of arguments expected.
361 | Error_Expr_Argument_mismatch (Exists_Type ty) (Exists_Type ty) ast
362 -- ^ Mismatch between respectively expected and actual type when applying a function.
363 | Error_Expr_Read Error_Read ast
364 -- ^ error when reading a literal.
365 | Error_Expr_Type err_ty ast
366 -- ^ Error when parsing a type.
367 | Error_Expr_Unsupported ast
368 -- ^ Given syntax is supported by none
369 -- of the expression parser components
370 -- of the expression stack.
371 | Error_Expr_Unsupported_here ast
372 -- ^ Given syntax not supported by the current expression parser component.
373 deriving (Eq, Show)
374
375 error_expr
376 :: Error_Expr_Lift
377 (Error_Expr (Error_of_Type ast (Type_Root_of_Expr ex)) (Type_Root_of_Expr ex) ast)
378 (Error_of_Expr ast (Root_of_Expr ex))
379 => Proxy ex
380 -> Error_Expr (Error_of_Type ast (Type_Root_of_Expr ex)) (Type_Root_of_Expr ex) ast
381 -> Error_of_Expr ast (Root_of_Expr ex)
382 error_expr _ = error_expr_lift