]> Git — Sourcephile - haskell/symantic.git/blob - Language/Symantic/Expr/Common.hs
init
[haskell/symantic.git] / Language / 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.Symantic.Expr.Common where
14
15 import Data.Maybe (fromMaybe)
16 import Data.Proxy (Proxy(..))
17 import Data.Text (Text)
18 import Data.Type.Equality ((:~:)(Refl))
19 import GHC.Prim (Constraint)
20 import qualified Data.Text as Text
21
22 import Language.Symantic.Type
23
24 -- * Class 'Expr_from'
25
26 -- | Parse given @ast@ into
27 -- a 'Type_Root_of_Expr' and
28 -- a 'Forall_Repr_with_Context',
29 -- or return an 'Error_of_Expr'.
30 class Expr_from ast (ex:: *) where
31 expr_from :: Expr_From ast ex hs ret
32
33 -- | Like 'expr_from' but for a root expression.
34 root_expr_from
35 :: forall lam ast root.
36 ( Expr_from ast root
37 , Root_of_Expr root ~ root )
38 => Proxy root -> Proxy lam -> ast
39 -> Either (Error_of_Expr ast root)
40 (Exists_Type_and_Repr (Type_Root_of_Expr root)
41 (Forall_Repr root))
42 root_expr_from _ex _lam ast =
43 expr_from (Proxy::Proxy root) ast
44 Context_Empty $ \ty (Forall_Repr_with_Context repr) ->
45 Right $ Exists_Type_and_Repr ty $
46 Forall_Repr $ repr Context_Empty
47
48 -- ** Type 'Expr_From'
49 type Expr_From ast ex hs ret
50 = Proxy ex
51 -- ^ Select the 'Expr_from' instance.
52 -> ast
53 -- ^ The input data to parse.
54 -> Context (Lambda_Var (Type_Root_of_Expr ex)) hs
55 -- ^ The bound variables in scope and their types:
56 -- held in the heterogeneous list @hs@,
57 -- from the closest including lambda abstraction to the farest.
58 -> ( forall h
59 . Type_Root_of_Expr ex h
60 -> Forall_Repr_with_Context ex hs h
61 -> Either (Error_of_Expr ast (Root_of_Expr ex)) ret )
62 -- ^ The accumulating continuation.
63 -> Either (Error_of_Expr ast (Root_of_Expr ex)) ret
64
65 -- | Parse a literal.
66 lit_from
67 :: forall ty lit ex ast hs ret.
68 ( ty ~ Type_Root_of_Expr ex
69 , Read lit
70 , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
71 (Error_of_Expr ast (Root_of_Expr ex))
72 ) => (forall repr. Sym_of_Expr ex repr => lit -> repr lit)
73 -> ty lit -> Lambda_Var_Name
74 -> Expr_From ast ex hs ret
75 lit_from lit ty_lit toread ex ast _ctx k =
76 case read_safe toread of
77 Left err -> Left $ error_expr ex $ Error_Expr_Read err ast
78 Right (i::lit) -> k ty_lit $ Forall_Repr_with_Context $ const $ lit i
79
80 -- | Parse a unary operator.
81 op1_from
82 :: forall root ty lit ex ast hs ret.
83 ( ty ~ Type_Root_of_Expr ex
84 , root ~ Root_of_Expr ex
85 , Eq_Type (Type_Root_of_Expr root)
86 , Expr_from ast root
87 , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
88 (Error_of_Expr ast root)
89 , Root_of_Expr root ~ root
90 ) => (forall repr. Sym_of_Expr ex repr => repr lit -> repr lit)
91 -> ty lit -> ast
92 -> Expr_From ast ex hs ret
93 op1_from op ty_lit ast_x ex ast ctx k =
94 expr_from (Proxy::Proxy root) ast_x ctx $
95 \ty_x (Forall_Repr_with_Context x) ->
96 check_eq_type ex ast ty_lit ty_x $ \Refl ->
97 k ty_x $ Forall_Repr_with_Context (op . x)
98
99 -- | Parse a binary operator.
100 op2_from
101 :: forall root ty lit ex ast hs ret.
102 ( ty ~ Type_Root_of_Expr ex
103 , root ~ Root_of_Expr ex
104 , Eq_Type (Type_Root_of_Expr root)
105 , Expr_from ast root
106 , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
107 (Error_of_Expr ast root)
108 , Root_of_Expr root ~ root
109 ) => (forall repr. Sym_of_Expr ex repr => repr lit -> repr lit -> repr lit)
110 -> ty lit -> ast -> ast
111 -> Expr_From ast ex hs ret
112 op2_from op ty_lit ast_x ast_y ex ast ctx k =
113 expr_from (Proxy::Proxy root) ast_x ctx $ \ty_x (Forall_Repr_with_Context x) ->
114 expr_from (Proxy::Proxy root) ast_y ctx $ \ty_y (Forall_Repr_with_Context y) ->
115 check_eq_type ex ast ty_lit ty_x $ \Refl ->
116 check_eq_type ex ast ty_lit ty_y $ \Refl ->
117 k ty_x $ Forall_Repr_with_Context $
118 \c -> x c `op` y c
119
120 -- ** Type 'Context'
121
122 -- | GADT for a typing context,
123 -- accumulating an @item@ at each lambda;
124 -- used to accumulate object-types (in 'Expr_from')
125 -- or host-terms (in 'Repr_Host')
126 -- associated with the 'Lambda_Var's in scope.
127 data Context :: (* -> *) -> [*] -> * where
128 Context_Empty :: Context item '[]
129 Context_Next :: item h -> Context item hs -> Context item (h ': hs)
130 infixr 5 `Context_Next`
131
132 -- ** Type 'Lambda_Var'
133 -- | Join a name and a type.
134 --
135 -- This data type is used to handle lambda variables by name
136 -- (instead of DeBruijn indices for instance).
137 data Lambda_Var ty h
138 = Lambda_Var Lambda_Var_Name (ty h)
139 type Lambda_Var_Name = Text
140
141 -- ** Type 'Forall_Repr_with_Context'
142 -- | A data type embedding a universal quantification
143 -- over an interpreter @repr@
144 -- and qualified by the symantics of an expression.
145 --
146 -- Moreover the expression is abstracted by a 'Context'
147 -- built at parsing time to build a /Higher-Order Abstract Syntax/ (HOAS)
148 -- for lambda abstractions.
149 --
150 -- This data type is used to keep a parsed expression polymorphic enough
151 -- to stay interpretable by different interpreters.
152 --
153 -- NOTE: 'Sym_of_Expr'@ ex repr@
154 -- is needed to be able to use symantic methods of the parsed expression
155 -- into a 'Forall_Repr_with_Context'@ ex@.
156 --
157 -- NOTE: 'Sym_of_Expr'@ (@'Root_of_Expr'@ ex) repr@
158 -- is needed to be able to use an expression
159 -- out of a 'Forall_Repr_with_Context'@ (@'Root_of_Expr'@ ex)@
160 -- into a 'Forall_Repr_with_Context'@ ex@,
161 -- which happens when a symantic method includes a polymorphic type
162 -- and thus calls: 'expr_from'@ (Proxy::Proxy (@'Root_of_Expr'@ ex))@.
163 data Forall_Repr_with_Context ex hs h
164 = Forall_Repr_with_Context
165 ( forall repr. ( Sym_of_Expr ex repr
166 , Sym_of_Expr (Root_of_Expr ex) repr
167 ) => Context repr hs -> repr h )
168
169 -- ** Type 'Forall_Repr'
170 data Forall_Repr ex h
171 = Forall_Repr
172 { unForall_Repr :: forall repr
173 . ( Sym_of_Expr ex repr
174 , Sym_of_Expr (Root_of_Expr ex) repr )
175 => repr h }
176
177 -- ** Type family 'Root_of_Expr'
178 -- | The root expression of an expression.
179 type family Root_of_Expr (ex:: *) :: *
180
181 -- ** Type family 'Sym_of_Expr'
182 -- | The symantic of an expression.
183 type family Sym_of_Expr (ex:: *) (repr:: * -> *) :: Constraint
184
185 -- ** Type family 'Error_of_Expr'
186 -- | The error(s) of an expression.
187 type family Error_of_Expr (ast:: *) (ex:: *) :: *
188
189 -- ** Type family 'Type_of_Expr'
190 -- | The type of an expression, parameterized by a root type.
191 type family Type_of_Expr (ex:: *) :: {-root-}(* -> *) -> {-h-}* -> *
192
193 -- ** Type 'Type_Root_of_Expr'
194 -- | Convenient alias.
195 --
196 -- NOTE: include 'Type_Var' only to use it
197 -- within 'Error_Expr_Type_mismatch' so far.
198 type Type_Root_of_Expr (ex:: *)
199 = Type_Root (Type_Var0 :|: Type_Var1 :|: Type_of_Expr (Root_of_Expr ex))
200
201 -- * Type 'Expr_Root'
202 -- | The root expression, passing itself as parameter to the given expression.
203 newtype Expr_Root (ex:: * -> *)
204 = Expr_Root (ex (Expr_Root ex))
205 type instance Root_of_Expr (Expr_Root ex) = Expr_Root ex
206 type instance Type_of_Expr (Expr_Root ex)
207 = Type_of_Expr (ex (Expr_Root ex))
208 type instance Error_of_Expr ast (Expr_Root ex)
209 = Error_Expr_Alt (Error_Expr (Error_of_Type ast (Type_Root_of_Expr (ex (Expr_Root ex))))
210 (Type_Root_of_Expr (ex (Expr_Root ex)))
211 ast)
212 (Error_of_Expr ast (ex (Expr_Root ex)))
213 type instance Sym_of_Expr (Expr_Root ex) repr
214 = Sym_of_Expr (ex (Expr_Root ex)) repr
215 instance -- Expr_from
216 ( Expr_from ast (ex (Expr_Root ex))
217 , Root_of_Expr (ex (Expr_Root ex)) ~ Expr_Root ex
218 ) => Expr_from ast (Expr_Root ex) where
219 expr_from _ex ctx ast k =
220 expr_from (Proxy::Proxy (ex (Expr_Root ex)))
221 ctx ast $ \ty (Forall_Repr_with_Context repr) ->
222 k ty (Forall_Repr_with_Context repr)
223
224 {- NOTE: useless code so far.
225 -- ** Class 'Expr_Root_Lift'
226 -- | Lift a given expression to a given root expression.
227 class Expr_Root_Lift ex root where
228 expr_root_lift :: ex root -> root
229 instance
230 Lift_Expr ex root =>
231 Expr_Root_Lift ex (Expr_Root root) where
232 expr_root_lift = Expr_Root . lift_expr
233 -}
234
235 -- * Type 'Expr_Alt'
236 -- | Expression making an alternative between two expressions.
237 data Expr_Alt curr next (root:: *)
238 = Expr_Alt_Curr (curr root)
239 | Expr_Alt_Next (next root)
240 -- | Convenient alias. Requires @TypeOperators@.
241 --
242 -- TODO: see if using a type-level list is better.
243 type (.|.) = Expr_Alt
244 infixr 5 .|.
245 type instance Root_of_Expr (Expr_Alt curr next root) = root
246 type instance Sym_of_Expr (Expr_Alt curr next root) repr
247 = ( Sym_of_Expr (curr root) repr
248 , Sym_of_Expr (next root) repr
249 )
250 type instance Type_of_Expr (Expr_Alt curr next root)
251 = Type_of_Expr_Alt (Type_of_Expr (curr root))
252 (Type_of_Expr (next root))
253 -- ** Type family 'Type_of_Expr_Alt'
254 -- | Remove 'No_Type' type when building 'Type_of_Expr'.
255 type family Type_of_Expr_Alt
256 (type_curr:: (* -> *) -> * -> *)
257 (type_next:: (* -> *) -> * -> *)
258 where
259 Type_of_Expr_Alt No_Type next = next
260 Type_of_Expr_Alt curr No_Type = curr
261 Type_of_Expr_Alt curr next = Type_Alt curr next
262
263 type instance Error_of_Expr ast (Expr_Alt curr next root)
264 = Error_of_Expr_Alt ast (Error_of_Expr ast (curr root))
265 (Error_of_Expr ast (next root))
266 -- ** Type family 'Error_of_Expr_Alt'
267 -- | Remove 'No_Error_Expr' type when building the error of an expression.
268 type family Error_of_Expr_Alt ast curr next where
269 Error_of_Expr_Alt ast No_Error_Expr next = next
270 Error_of_Expr_Alt ast curr No_Error_Expr = curr
271 Error_of_Expr_Alt ast curr next = Error_Expr_Alt curr next
272
273 -- ** Type 'No_Error_Expr'
274 -- | A discarded error.
275 data No_Error_Expr
276 = No_Error_Expr
277 deriving (Eq, Show)
278
279 instance -- Expr_from
280 ( Expr_from ast (curr root)
281 , Expr_from ast (next root)
282 , Root_of_Expr (curr root) ~ root
283 , Root_of_Expr (next root) ~ root
284 , Unlift_Error_Expr (Error_Expr (Error_of_Type ast (Type_Root_of_Expr root))
285 (Type_Root_of_Expr root) ast)
286 (Error_of_Expr ast root)
287 ) => Expr_from ast (Expr_Alt curr next root) where
288 expr_from _ex ctx ast k =
289 case expr_from (Proxy::Proxy (curr root)) ctx ast $
290 \ty (Forall_Repr_with_Context repr) ->
291 Right $ k ty (Forall_Repr_with_Context repr) of
292 Right ret -> ret
293 Left err ->
294 case unlift_error_expr err of
295 Just (Error_Expr_Unsupported_here _
296 :: Error_Expr (Error_of_Type ast (Type_Root_of_Expr root))
297 (Type_Root_of_Expr root) ast) ->
298 expr_from (Proxy::Proxy (next root)) ctx ast $
299 \ty (Forall_Repr_with_Context repr) ->
300 k ty (Forall_Repr_with_Context repr)
301 _ -> Left err
302
303 {- NOTE: useless code so far.
304 -- ** Type 'Lift_Expr'
305 -- | Apply 'Peano_of_Expr' on 'Lift_ExprP'.
306 type Lift_Expr ex exs
307 = Lift_ExprP (Peano_of_Expr ex exs) ex exs
308
309 -- | Convenient wrapper around 'expr_liftN',
310 -- passing it the 'Peano' number from 'Peano_of_Expr'.
311 lift_expr
312 :: forall ex exs (root:: *).
313 Lift_Expr ex exs =>
314 ex root -> exs root
315 lift_expr = expr_liftN (Proxy::Proxy (Peano_of_Expr ex exs))
316
317 -- *** Type family 'Peano_of_Expr'
318 -- | Return a 'Peano' number derived from the location
319 -- of a given expression within a given expression stack,
320 -- which is used to avoid @OverlappingInstances@.
321 type family Peano_of_Expr
322 (ex:: * -> *)
323 (exs:: * -> *) :: * where
324 Peano_of_Expr ex ex = Zero
325 Peano_of_Expr ex (Expr_Alt ex next) = Zero
326 Peano_of_Expr other (Expr_Alt curr next) = Succ (Peano_of_Expr other next)
327
328 -- *** Class 'Lift_ExprP'
329 -- | Lift a given expression to the top of a given expression stack including it,
330 -- by constructing the appropriate sequence of 'Expr_Alt_Curr' and 'Expr_Alt_Next'.
331 class Lift_ExprP (p:: *) ex exs where
332 expr_liftN :: forall (root:: *). Proxy p -> ex root -> exs root
333 instance Lift_ExprP Zero curr curr where
334 expr_liftN _ = id
335 instance Lift_ExprP Zero curr (Expr_Alt curr next) where
336 expr_liftN _ = Expr_Alt_Curr
337 instance
338 Lift_ExprP p other next =>
339 Lift_ExprP (Succ p) other (Expr_Alt curr next) where
340 expr_liftN _ = Expr_Alt_Next . expr_liftN (Proxy::Proxy p)
341
342 -- ** Type 'Unlift_Expr'
343 -- | Apply 'Peano_of_Expr' on 'Expr_UnliftN'.
344 type Unlift_Expr ex exs
345 = Expr_UnliftN (Peano_of_Expr ex exs) ex exs
346
347 -- | Convenient wrapper around 'expr_unliftN',
348 -- passing it the 'Peano' number from 'Peano_of_Expr'.
349 expr_unlift
350 :: forall ex exs (root:: *).
351 Unlift_Expr ex exs =>
352 exs root -> Maybe (ex root)
353 expr_unlift = expr_unliftN (Proxy::Proxy (Peano_of_Expr ex exs))
354
355 -- *** Class 'Expr_UnliftN'
356 -- | Try to unlift a given expression out of a given expression stack including it,
357 -- by deconstructing the appropriate sequence of 'Expr_Alt_Curr' and 'Expr_Alt_Next'.
358 class Expr_UnliftN (p:: *) ex exs where
359 expr_unliftN :: forall (root:: *). Proxy p -> exs root -> Maybe (ex root)
360 instance Expr_UnliftN Zero curr curr where
361 expr_unliftN _ = Just
362 instance Expr_UnliftN Zero curr (Expr_Alt curr next) where
363 expr_unliftN _ (Expr_Alt_Curr x) = Just x
364 expr_unliftN _ (Expr_Alt_Next _) = Nothing
365 instance
366 Expr_UnliftN p other next =>
367 Expr_UnliftN (Succ p) other (Expr_Alt curr next) where
368 expr_unliftN _ (Expr_Alt_Next x) = expr_unliftN (Proxy::Proxy p) x
369 expr_unliftN _ (Expr_Alt_Curr _) = Nothing
370 -}
371
372 -- ** Type family 'Is_Last_Expr'
373 -- | Return whether a given expression is the last one in a given expression stack.
374 --
375 -- NOTE: each expression parser uses this type family
376 -- when it encounters unsupported syntax:
377 -- to know if it is the last expression parser component that will be tried
378 -- (and thus return 'Error_Expr_Unsupported')
379 -- or if some other expression parser component shall be tried
380 -- (and thus return 'Error_Expr_Unsupported_here',
381 -- which is then handled accordingly by the 'Expr_from' instance of 'Expr_Alt').
382 type family Is_Last_Expr (ex:: *) (exs:: *) :: Bool where
383 Is_Last_Expr ex ex = 'True
384 Is_Last_Expr ex (Expr_Root exs) = Is_Last_Expr ex (exs (Expr_Root exs))
385 Is_Last_Expr (ex root) (Expr_Alt ex next root) = 'False
386 Is_Last_Expr other (Expr_Alt curr next root) = Is_Last_Expr other (next root)
387
388 -- * Type 'Error_Expr_Alt'
389 -- | Error expression making an alternative between two error expressions.
390 data Error_Expr_Alt curr next
391 = Error_Expr_Alt_Curr curr
392 | Error_Expr_Alt_Next next
393 deriving (Eq, Show)
394
395 -- ** Type 'Lift_Error_Expr'
396 -- | Apply 'Peano_of_Error_Expr' on 'Lift_Error_ExprP'.
397 type Lift_Error_Expr err errs
398 = Lift_Error_ExprP (Peano_of_Error_Expr err errs) err errs
399
400 -- | Convenient wrapper around 'lift_error_exprP',
401 -- passing it the 'Peano' number from 'Peano_of_Error_Expr'.
402 lift_error_expr
403 :: forall err errs.
404 Lift_Error_Expr err errs => err -> errs
405 lift_error_expr = lift_error_exprP (Proxy::Proxy (Peano_of_Error_Expr err errs))
406
407 -- *** Type family 'Peano_of_Error_Expr'
408 -- | Return a 'Peano' number derived from the location
409 -- of a given error expression within a given error expression stack,
410 -- which is used to avoid @OverlappingInstances@.
411 type family Peano_of_Error_Expr (err:: *) (errs:: *) :: * where
412 Peano_of_Error_Expr err err = Zero
413 Peano_of_Error_Expr err (Error_Expr_Alt err next) = Zero
414 Peano_of_Error_Expr other (Error_Expr_Alt curr next) = Succ (Peano_of_Error_Expr other next)
415
416 -- *** Class 'Lift_Error_ExprP'
417 -- | Lift a given expression to the top of a given expression stack including it,
418 -- by constructing the appropriate sequence of 'Error_Expr_Alt_Curr' and 'Error_Expr_Alt_Next'.
419 class Lift_Error_ExprP (p:: *) err errs where
420 lift_error_exprP :: Proxy p -> err -> errs
421 instance Lift_Error_ExprP Zero curr curr where
422 lift_error_exprP _ = id
423 instance Lift_Error_ExprP Zero curr (Error_Expr_Alt curr next) where
424 lift_error_exprP _ = Error_Expr_Alt_Curr
425 instance
426 Lift_Error_ExprP p other next =>
427 Lift_Error_ExprP (Succ p) other (Error_Expr_Alt curr next) where
428 lift_error_exprP _ = Error_Expr_Alt_Next . lift_error_exprP (Proxy::Proxy p)
429
430 -- ** Type 'Unlift_Error_Expr'
431 -- | Apply 'Peano_of_Error_Expr' on 'Unlift_Error_ExprP'.
432 type Unlift_Error_Expr ex exs
433 = Unlift_Error_ExprP (Peano_of_Error_Expr ex exs) ex exs
434
435 -- | Convenient wrapper around 'unlift_error_exprP',
436 -- passing it the 'Peano' number from 'Peano_of_Error_Expr'.
437 unlift_error_expr
438 :: forall ex exs.
439 Unlift_Error_Expr ex exs => exs -> Maybe ex
440 unlift_error_expr = unlift_error_exprP (Proxy::Proxy (Peano_of_Error_Expr ex exs))
441
442 -- *** Class 'Unlift_Error_ExprP'
443 -- | Try to unlift a given expression error out of a given expression error stack including it,
444 -- by deconstructing the appropriate sequence of 'Error_Expr_Alt_Curr' and 'Error_Expr_Alt_Next'.
445 class Unlift_Error_ExprP (p:: *) ex exs where
446 unlift_error_exprP :: Proxy p -> exs -> Maybe ex
447 instance Unlift_Error_ExprP Zero curr curr where
448 unlift_error_exprP _ = Just
449 instance Unlift_Error_ExprP Zero curr (Error_Expr_Alt curr next) where
450 unlift_error_exprP _ (Error_Expr_Alt_Curr x) = Just x
451 unlift_error_exprP _ (Error_Expr_Alt_Next _) = Nothing
452 instance
453 Unlift_Error_ExprP p other next =>
454 Unlift_Error_ExprP (Succ p) other (Error_Expr_Alt curr next) where
455 unlift_error_exprP _ (Error_Expr_Alt_Next x) = unlift_error_exprP (Proxy::Proxy p) x
456 unlift_error_exprP _ (Error_Expr_Alt_Curr _) = Nothing
457
458 -- * Type 'Error_Expr_Read'
459 -- | Common expression errors.
460 data Error_Expr err_ty ty ast
461 = Error_Expr_Wrong_number_of_arguments ast Int
462 -- ^ Wrong number of arguments applied to a term,
463 -- the integer is the number of arguments expected.
464 | Error_Expr_Type_mismatch ast (Exists_Type ty) (Exists_Type ty)
465 -- ^ Mismatch between respectively expected and actual type.
466 | Error_Expr_Constraint_missing ast {-Exists_Dict-} (Exists_Type ty)
467 -- ^ A 'Constraint' is missing.
468 | Error_Expr_Read Error_Read ast
469 -- ^ Error when reading a literal.
470 | Error_Expr_Type err_ty ast
471 -- ^ Error when parsing a type.
472 | Error_Expr_Unsupported ast
473 -- ^ Given syntax is supported by none
474 -- of the expression parser components
475 -- of the expression stack.
476 | Error_Expr_Unsupported_here ast
477 -- ^ Given syntax not supported by
478 -- the current expression parser component.
479 deriving (Eq, Show)
480
481 -- | Convenient type alias.
482 type Error_Expr_of_Root ast root
483 = Error_Expr (Error_of_Type ast (Type_Root_of_Expr root))
484 (Type_Root_of_Expr root)
485 ast
486
487 -- | Convenient wrapper around 'lift_error_expr',
488 -- passing the type family boilerplate.
489 error_expr
490 :: forall ast ex ty.
491 (ty ~ Type_Root_of_Expr ex)
492 => Lift_Error_Expr
493 (Error_Expr (Error_of_Type ast ty) ty ast)
494 (Error_of_Expr ast (Root_of_Expr ex))
495 => Proxy ex
496 -> Error_Expr (Error_of_Type ast ty) ty ast
497 -> Error_of_Expr ast (Root_of_Expr ex)
498 error_expr _ = lift_error_expr
499
500 -- | Parsing utility to return 'Error_Expr_Unsupported'
501 -- or 'Error_Expr_Unsupported_here'
502 -- according to the given expression.
503 error_expr_unsupported
504 :: forall ast ex ty root.
505 ( root ~ Root_of_Expr ex
506 , ty ~ Type_Root_of_Expr ex
507 , Implicit_HBool (Is_Last_Expr ex root)
508 , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
509 (Error_of_Expr ast root)
510 ) => Proxy ex -> ast
511 -> Error_of_Expr ast (Root_of_Expr ex)
512 error_expr_unsupported ex ast =
513 case hbool :: HBool (Is_Last_Expr ex root) of
514 HTrue -> error_expr ex $ Error_Expr_Unsupported ast
515 HFalse -> error_expr ex $ Error_Expr_Unsupported_here ast
516
517 -- | Parsing utility to check that two types are equal,
518 -- or raise 'Error_Expr_Type_mismatch'.
519 check_eq_type
520 :: forall ast ex root ty x y ret.
521 ( root ~ Root_of_Expr ex
522 , ty ~ Type_Root_of_Expr ex
523 , Eq_Type ty
524 , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
525 (Error_of_Expr ast root)
526 )
527 => Proxy ex -> ast -> ty x -> ty y
528 -> (x :~: y -> Either (Error_of_Expr ast root) ret)
529 -> Either (Error_of_Expr ast root) ret
530 check_eq_type ex ast x y k =
531 case x `eq_type` y of
532 Just Refl -> k Refl
533 Nothing -> Left $ error_expr ex $
534 Error_Expr_Type_mismatch ast
535 (Exists_Type x)
536 (Exists_Type y)
537 check_eq_type1
538 :: forall ast ex root ty h1 h2 a1 a2 ret.
539 ( root ~ Root_of_Expr ex
540 , ty ~ Type_Root_of_Expr ex
541 , Eq_Type1 ty
542 , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
543 (Error_of_Expr ast root)
544 )
545 => Proxy ex -> ast -> ty (h1 a1) -> ty (h2 a2)
546 -> (h1 :~: h2 -> Either (Error_of_Expr ast root) ret)
547 -> Either (Error_of_Expr ast root) ret
548 check_eq_type1 ex ast h1 h2 k =
549 case h1 `eq_type1` h2 of
550 Just Refl -> k Refl
551 Nothing -> Left $ error_expr ex $
552 Error_Expr_Type_mismatch ast
553 (Exists_Type h1)
554 (Exists_Type h2)
555
556 -- | Parsing utility to check that a type is has instance of a given 'Constraint',
557 -- or raise 'Error_Expr_Constraint_missing'.
558 check_constraint_type
559 :: forall ast ex c root ty h ret.
560 ( root ~ Root_of_Expr ex
561 , ty ~ Type_Root_of_Expr ex
562 , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
563 (Error_of_Expr ast root)
564 , Constraint_Type c ty
565 )
566 => Proxy ex -> Proxy c -> ast -> ty h
567 -> (Dict (c h) -> Either (Error_of_Expr ast root) ret)
568 -> Either (Error_of_Expr ast root) ret
569 check_constraint_type ex c ast ty k =
570 case constraint_type c ty of
571 Just Dict -> k Dict
572 Nothing -> Left $ error_expr ex $
573 Error_Expr_Constraint_missing ast
574 {-(Exists_Dict c)-}
575 -- FIXME: not easy to report the constraint
576 -- and still support 'Eq' and 'Show' deriving.
577 (Exists_Type ty)
578
579 -- | Parsing utility to check that a type is has instance of a given 'Constraint'1,
580 -- or raise 'Error_Expr_Constraint_missing'.
581 check_constraint1_type
582 :: forall ast ex c root ty h a ret.
583 ( root ~ Root_of_Expr ex
584 , ty ~ Type_Root_of_Expr ex
585 , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
586 (Error_of_Expr ast root)
587 , Constraint_Type1 c ty
588 )
589 => Proxy ex -> Proxy c -> ast -> ty (h a)
590 -> (Dict (c h) -> Either (Error_of_Expr ast root) ret)
591 -> Either (Error_of_Expr ast root) ret
592 check_constraint1_type ex c ast ty k =
593 case constraint_type1 c ty of
594 Just Dict -> k Dict
595 Nothing -> Left $ error_expr ex $
596 Error_Expr_Constraint_missing ast
597 (Exists_Type ty)
598
599 -- | Parsing utility to check that the given type is a 'Type_Type1'
600 -- or raise 'Error_Expr_Type_mismatch'.
601 check_type1
602 :: forall ast ex root ty h ret.
603 ( root ~ Root_of_Expr ex
604 , ty ~ Type_Root_of_Expr ex
605 , Unlift_Type1 (Type_of_Expr root)
606 , String_from_Type ty
607 , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
608 (Error_of_Expr ast root)
609 )
610 => Proxy ex -> ast -> ty h
611 -> (forall (t1:: *).
612 ( Type_Type1 t1 ty h
613 , Lift_Type1 t1 (Type_Var0 :|: Type_Var1 :|: Type_of_Expr root)
614 ) -> Either (Error_of_Expr ast root) ret)
615 -> Either (Error_of_Expr ast root) ret
616 check_type1 ex ast ty k =
617 (`fromMaybe` unlift_type1 (unType_Root ty) (Just . k)) $
618 Left $
619 error_expr ex $
620 Error_Expr_Type_mismatch ast
621 (Exists_Type (type_var1 SZero (type_var0 SZero)
622 :: Type_Root_of_Expr ex (Var1 Var0)))
623 (Exists_Type ty)
624
625 -- * Type 'Error_Read'
626 -- | Error parsing a host-term.
627 data Error_Read
628 = Error_Read Text
629 deriving (Eq, Show)
630
631 -- | Parse a host-term.
632 read_safe :: Read h => Text -> Either Error_Read h
633 read_safe t =
634 case reads $ Text.unpack t of
635 [(x, "")] -> Right x
636 _ -> Left $ Error_Read t