]> Git — Sourcephile - haskell/symantic.git/blob - Language/Symantic/Type/Common.hs
init
[haskell/symantic.git] / Language / Symantic / Type / Common.hs
1 {-# LANGUAGE ConstraintKinds #-}
2 {-# LANGUAGE DataKinds #-}
3 {-# LANGUAGE DefaultSignatures #-}
4 {-# LANGUAGE ExistentialQuantification #-}
5 {-# LANGUAGE FlexibleContexts #-}
6 {-# LANGUAGE FlexibleInstances #-}
7 {-# LANGUAGE GADTs #-}
8 {-# LANGUAGE MultiParamTypeClasses #-}
9 {-# LANGUAGE Rank2Types #-}
10 {-# LANGUAGE ScopedTypeVariables #-}
11 {-# LANGUAGE TypeFamilies #-}
12 {-# LANGUAGE TypeOperators #-}
13 {-# LANGUAGE UndecidableInstances #-}
14 module Language.Symantic.Type.Common where
15
16 import Data.Maybe (isJust, fromMaybe)
17 import Data.Proxy
18 import Data.Type.Equality ((:~:)(Refl))
19 import Language.Symantic.Lib.Data.Peano
20 import GHC.Prim (Constraint)
21
22 -- * Class 'Eq_Type'
23 -- | Test two types for equality,
24 -- returning an Haskell type-level proof
25 -- of the equality when it holds.
26 class Eq_Type (ty:: * -> *) where
27 eq_type :: forall h1 h2. ty h1 -> ty h2 -> Maybe (h1 :~: h2)
28
29 -- * Class 'Eq_Type1'
30 -- | Test two type constructors for equality,
31 -- returning an Haskell type-level proof
32 -- of the equality when it holds.
33 class Eq_Type1 (ty:: * -> *) where
34 eq_type1 :: forall h1 h2 a1 a2. ty (h1 a1) -> ty (h2 a2) -> Maybe (h1 :~: h2)
35 eq_type1 = error "eq_type1"
36
37 -- * Class 'Constraint_Type'
38 -- | Test if a type satisfies a given 'Constraint',
39 -- returning an Haskell type-level proof
40 -- of that satisfaction when it holds.
41 class Constraint_Type (c:: * -> Constraint) (ty:: * -> *) where
42 constraint_type :: forall h. Proxy c -> ty h -> Maybe (Dict (c h))
43 constraint_type _c _ = Nothing
44
45 -- * Class 'Constraint_Type1'
46 -- | Test if a type constructor satisfies a given 'Constraint',
47 -- returning an Haskell type-level proof
48 -- of that satisfaction when it holds.
49 class Constraint_Type1 (c:: (* -> *) -> Constraint) (ty:: * -> *) where
50 constraint_type1 :: forall h1 h. Proxy c -> ty (h1 h) -> Maybe (Dict (c h1))
51 constraint_type1 _c _ = Nothing
52
53 -- ** Type 'Dict'
54 -- | 'Dict' captures the dictionary of a 'Constraint':
55 -- pattern matching on the 'Dict' constructor
56 -- brings the 'Constraint' into scope.
57 data Dict :: Constraint -> * where
58 Dict :: c => Dict c
59
60 -- * Type 'Exists_Dict'
61 data Exists_Dict
62 = forall c. Exists_Dict (Dict c)
63
64 -- * Class 'Type_from'
65 -- | Parse given @ast@ into a 'Root_of_Type',
66 -- or return an 'Error_of_Type'.
67 --
68 -- NOTE: making a distinction between @ty@ and 'Root_of_Type'@ ty@,
69 -- instead of having only a @root@ variable
70 -- is what enables to define many instances, one per type.
71 class Type_from ast (ty:: * -> *) where
72 type_from
73 :: Proxy ty
74 -> ast
75 -> (forall h. Root_of_Type ty h
76 -> Either (Error_of_Type ast (Root_of_Type ty)) ret)
77 -> Either (Error_of_Type ast (Root_of_Type ty)) ret
78
79 -- * Class 'Type1_from'
80 -- | Parse given @ast@ into a 'Root_of_Type' constructor,
81 -- or return an 'Error_of_Type'.
82 class Type1_from ast (ty:: * -> *) where
83 type1_from
84 :: Proxy ty
85 -> ast
86 -> (forall (f:: * -> *). Proxy f
87 -> (forall h. Root_of_Type ty h -> Root_of_Type ty (f h))
88 -> Either (Error_of_Type ast (Root_of_Type ty)) ret)
89 -> Either (Error_of_Type ast (Root_of_Type ty)) ret
90 default type1_from ::
91 ( Lift_Error_Type (Error_Type ast) (Error_of_Type ast (Root_of_Type ty))
92 , Implicit_HBool (Is_Last_Type ty (Root_of_Type ty))
93 ) => Proxy ty
94 -> ast
95 -> (forall (f:: * -> *). Proxy f
96 -> (forall h. Root_of_Type ty h -> Root_of_Type ty (f h))
97 -> Either (Error_of_Type ast (Root_of_Type ty)) ret)
98 -> Either (Error_of_Type ast (Root_of_Type ty)) ret
99 type1_from ty ast _k =
100 Left $ error_type_unsupported ty ast
101
102 {-
103 class Type1_f_from (ty:: * -> *) where
104 type1_f_from
105 :: Proxy ty
106 -> (Root_of_Type ty) h_any
107 -> (forall (f:: * -> *). Proxy f
108 -> (forall h. (Root_of_Type ty) h -> (Root_of_Type ty) (f h))
109 -> Either ({-Error_of_Type ast (Root_of_Type ty)-}) ret)
110 -> Either ({-Error_of_Type ast (Root_of_Type ty)-}) ret
111 instance -- Type1_f_from
112 ( Eq_Type (curr root)
113 , Type1_f_from ast (curr root)
114 , Type1_f_from ast (next root)
115 , Root_of_Type (curr root) ~ root
116 , Root_of_Type (next root) ~ root
117 -- , Unlift_Error_Type (Error_Type ast) (Error_of_Type ast root)
118 ) => Type1_from ast (Type_Alt curr next root) where
119 type1_from _ty ast k =
120 case type1_from (Proxy::Proxy (curr root)) ast (\f ty -> Right $ k f ty) of
121 Right ret -> ret
122 Left err ->
123 case unlift_error_type err of
124 Just (Error_Type_Unsupported_here (_::ast)) ->
125 type1_from (Proxy::Proxy (next root)) ast k
126 _ -> Left err
127 -}
128
129 -- ** Type family 'Root_of_Type'
130 -- | Return the root type of a type.
131 type family Root_of_Type (ty:: * -> *) :: * -> *
132
133 -- ** Type family 'Error_of_Type'
134 -- | Return the error type of a type.
135 type family Error_of_Type (ast:: *) (ty:: * -> *) :: *
136
137 -- * Type 'No_Type'
138 -- | A discarded type.
139 data No_Type (root:: * -> *) h
140 = No_Type (root h)
141 deriving (Eq, Show)
142
143 -- * Type 'Type_Root'
144 -- | The root type, passing itself as parameter to the given type.
145 newtype Type_Root (ty:: (* -> *) -> * -> *) h
146 = Type_Root { unType_Root :: ty (Type_Root ty) h }
147 type instance Root_of_Type (Type_Root ty) = Type_Root ty
148 -- type instance Root_of_Type (ty (Type_Root ty)) = Type_Root ty
149 type instance Error_of_Type ast (Type_Root ty)
150 = Error_Type_Alt (Error_Type ast)
151 (Error_of_Type ast (ty (Type_Root ty)))
152 instance -- Eq_Type
153 Eq_Type (ty (Type_Root ty)) =>
154 Eq_Type (Type_Root ty) where
155 eq_type (Type_Root x) (Type_Root y) = x `eq_type` y
156 instance -- Eq_Type1
157 Eq_Type1 (ty (Type_Root ty)) =>
158 Eq_Type1 (Type_Root ty) where
159 eq_type1 (Type_Root x) (Type_Root y) = x `eq_type1` y
160 instance -- Eq
161 Eq_Type (Type_Root ty) =>
162 Eq (Type_Root ty h) where
163 x == y = isJust $ x `eq_type` y
164 instance -- Constraint_Type c Type_Root
165 Constraint_Type c (ty (Type_Root ty)) =>
166 Constraint_Type c (Type_Root ty) where
167 constraint_type c (Type_Root ty) = constraint_type c ty
168 instance -- Constraint_Type1 c Type_Root
169 Constraint_Type1 c (ty (Type_Root ty)) =>
170 Constraint_Type1 c (Type_Root ty) where
171 constraint_type1 c (Type_Root ty) = constraint_type1 c ty
172 instance -- Type_from
173 ( Eq_Type (Type_Root ty)
174 , Type_from ast (ty (Type_Root ty))
175 , Root_of_Type (ty (Type_Root ty)) ~ Type_Root ty
176 ) => Type_from ast (Type_Root ty) where
177 type_from _ty = type_from (Proxy::Proxy (ty (Type_Root ty)))
178 instance -- Type1_from
179 ( Eq_Type (Type_Root ty)
180 , Type1_from ast (ty (Type_Root ty))
181 , Root_of_Type (ty (Type_Root ty)) ~ Type_Root ty
182 ) => Type1_from ast (Type_Root ty) where
183 type1_from _ty = type1_from (Proxy::Proxy (ty (Type_Root ty)))
184 instance -- String_from_Type
185 String_from_Type (ty (Type_Root ty)) =>
186 String_from_Type (Type_Root ty) where
187 string_from_type (Type_Root ty) = string_from_type ty
188 instance -- Show
189 String_from_Type (Type_Root ty) =>
190 Show (Type_Root ty h) where
191 show = string_from_type
192
193 -- ** Class 'Lift_Type_Root'
194 -- | Lift a given type to a given root type.
195 class Lift_Type_Root ty root where
196 lift_type_root :: forall h. ty root h -> root h
197 instance
198 Lift_Type ty root =>
199 Lift_Type_Root ty (Type_Root root) where
200 lift_type_root = Type_Root . lift_type
201
202 -- * Type 'Type_Alt'
203 -- | Type making an alternative between two types.
204 data Type_Alt curr next (root:: * -> *) h
205 = Type_Alt_Curr (curr root h)
206 | Type_Alt_Next (next root h)
207 -- | Convenient alias. Requires @TypeOperators@.
208 type (:|:) = Type_Alt
209 infixr 5 :|:
210 type instance Root_of_Type (Type_Alt curr next root) = root
211 type instance Error_of_Type ast (Type_Alt curr next root)
212 = Error_of_Type_Alt ast (Error_of_Type ast (curr root))
213 (Error_of_Type ast (next root))
214 -- ** Type family 'Error_of_Type_Alt'
215 -- | Remove 'No_Error_Type' type when building 'Error_of_Type'.
216 type family Error_of_Type_Alt ast curr next where
217 Error_of_Type_Alt ast curr No_Error_Type = curr
218 Error_of_Type_Alt ast No_Error_Type next = next
219 Error_of_Type_Alt ast curr next = Error_Type_Alt curr next
220
221 -- ** Type 'No_Error_Type'
222 -- | A discarded error.
223 data No_Error_Type
224 = No_Error_Type
225 deriving (Eq, Show)
226
227 instance -- Eq_Type
228 ( Eq_Type (curr root)
229 , Eq_Type (next root)
230 ) => Eq_Type (Type_Alt curr next root) where
231 eq_type (Type_Alt_Curr x) (Type_Alt_Curr y) = x `eq_type` y
232 eq_type (Type_Alt_Next x) (Type_Alt_Next y) = x `eq_type` y
233 eq_type _ _ = Nothing
234 instance -- Eq_Type1
235 ( Eq_Type1 (curr root)
236 , Eq_Type1 (next root)
237 ) => Eq_Type1 (Type_Alt curr next root) where
238 eq_type1 (Type_Alt_Curr x) (Type_Alt_Curr y) = x `eq_type1` y
239 eq_type1 (Type_Alt_Next x) (Type_Alt_Next y) = x `eq_type1` y
240 eq_type1 _ _ = Nothing
241 instance -- Eq
242 ( Eq_Type (curr root)
243 , Eq_Type (next root)
244 ) => Eq (Type_Alt curr next root h) where
245 x == y = isJust $ x `eq_type` y
246 instance -- Constraint_Type c Type_Alt
247 ( Constraint_Type c (curr root)
248 , Constraint_Type c (next root)
249 ) => Constraint_Type c (Type_Alt curr next root) where
250 constraint_type c (Type_Alt_Curr ty) = constraint_type c ty
251 constraint_type c (Type_Alt_Next ty) = constraint_type c ty
252 instance -- Constraint_Type1 c Type_Alt
253 ( Constraint_Type1 c (curr root)
254 , Constraint_Type1 c (next root)
255 ) => Constraint_Type1 c (Type_Alt curr next root) where
256 constraint_type1 c (Type_Alt_Curr ty) = constraint_type1 c ty
257 constraint_type1 c (Type_Alt_Next ty) = constraint_type1 c ty
258 instance -- Type_from
259 ( Eq_Type (curr root)
260 , Type_from ast (curr root)
261 , Type_from ast (next root)
262 , Root_of_Type (curr root) ~ root
263 , Root_of_Type (next root) ~ root
264 , Unlift_Error_Type (Error_Type ast) (Error_of_Type ast root)
265 ) => Type_from ast (Type_Alt curr next root) where
266 type_from _ty ast k =
267 case type_from (Proxy::Proxy (curr root)) ast (Right . k) of
268 Right ret -> ret
269 Left err ->
270 case unlift_error_type err of
271 Just (Error_Type_Unsupported_here (_::ast)) ->
272 type_from (Proxy::Proxy (next root)) ast k
273 _ -> Left err
274 instance -- Type1_from
275 ( Eq_Type (curr root)
276 , Type1_from ast (curr root)
277 , Type1_from ast (next root)
278 , Root_of_Type (curr root) ~ root
279 , Root_of_Type (next root) ~ root
280 , Unlift_Error_Type (Error_Type ast) (Error_of_Type ast root)
281 ) => Type1_from ast (Type_Alt curr next root) where
282 type1_from _ty ast k =
283 case type1_from (Proxy::Proxy (curr root)) ast (\f ty -> Right $ k f ty) of
284 Right ret -> ret
285 Left err ->
286 case unlift_error_type err of
287 Just (Error_Type_Unsupported_here (_::ast)) ->
288 type1_from (Proxy::Proxy (next root)) ast k
289 _ -> Left err
290 instance -- String_from_Type
291 ( String_from_Type (curr root)
292 , String_from_Type (next root)
293 ) => String_from_Type (Type_Alt curr next root) where
294 string_from_type (Type_Alt_Curr t) = string_from_type t
295 string_from_type (Type_Alt_Next t) = string_from_type t
296
297 -- * Type 'Type_Type0'
298 -- | A type of kind @*@.
299 data Type_Type0 px (root:: * -> *) h where
300 Type_Type0 :: px -> Type_Type0 px root (Host_of px)
301
302 type instance Root_of_Type (Type_Type0 px root) = root
303 type instance Error_of_Type ast (Type_Type0 px root) = No_Error_Type
304
305 instance -- Eq_Type
306 Eq_Type (Type_Type0 (Proxy h0) root) where
307 eq_type Type_Type0{} Type_Type0{} = Just Refl
308 instance -- Eq_Type
309 Eq_Type (Type_Type0 EPeano root) where
310 eq_type (Type_Type0 p1)
311 (Type_Type0 p2)
312 | p1 == p2
313 = Just Refl
314 eq_type _ _ = Nothing
315 instance -- Eq
316 Eq_Type (Type_Type0 px root) =>
317 Eq (Type_Type0 px root h) where
318 x == y = isJust $ x `eq_type` y
319 instance -- Show
320 String_from_Type (Type_Type0 (Proxy h0) root) =>
321 Show (Type_Type0 (Proxy h0) root h0) where
322 show = string_from_type
323 instance Eq h0 => Constraint_Type Eq (Type_Type0 (Proxy h0) root) where
324 constraint_type _c Type_Type0{} = Just Dict
325 instance Ord h0 => Constraint_Type Ord (Type_Type0 (Proxy h0) root) where
326 constraint_type _c Type_Type0{} = Just Dict
327 instance Unlift_Type1 (Type_Type0 px)
328 instance Eq_Type1 (Type_Type0 (Proxy h0) root)
329
330 -- | Convenient alias to include a 'Type_Type0' within a type.
331 type_type0 :: forall root h0. Lift_Type_Root (Type_Type0 (Proxy h0)) root => root h0
332 type_type0 = lift_type_root (Type_Type0 (Proxy::Proxy h0))
333
334 -- ** Type family 'Host_of'
335 type family Host_of px :: *
336 type instance Host_of (Proxy h0) = h0
337
338 -- ** Type 'Lift_Type'
339 -- | Apply 'Peano_of_Type' on 'Lift_TypeP'.
340 type Lift_Type ty tys
341 = Lift_TypeP (Peano_of_Type ty tys) ty tys
342
343 -- *** Type 'Peano_of_Type'
344 -- | Return a 'Peano' number derived from the location
345 -- of a given type within a given type stack,
346 -- which is used to avoid @OverlappingInstances@.
347 type family Peano_of_Type
348 (ty:: (* -> *) -> * -> *)
349 (tys:: (* -> *) -> * -> *) :: * where
350 Peano_of_Type ty ty = Zero
351 Peano_of_Type ty (Type_Alt ty next) = Zero
352 Peano_of_Type other (Type_Alt curr next) = Succ (Peano_of_Type other next)
353
354 -- *** Class 'Lift_TypeP'
355 -- | Lift a given type to the top of a given type stack including it,
356 -- by constructing the appropriate sequence of 'Type_Alt_Curr' and 'Type_Alt_Next'.
357 class Lift_TypeP (p:: *) ty tys where
358 lift_typeP :: forall (root:: * -> *) h. Proxy p -> ty root h -> tys root h
359 instance Lift_TypeP Zero curr curr where
360 lift_typeP _ = id
361 instance Lift_TypeP Zero curr (Type_Alt curr next) where
362 lift_typeP _ = Type_Alt_Curr
363 instance
364 Lift_TypeP p other next =>
365 Lift_TypeP (Succ p) other (Type_Alt curr next) where
366 lift_typeP _ = Type_Alt_Next . lift_typeP (Proxy::Proxy p)
367
368 -- | Convenient wrapper around 'lift_typeP',
369 -- passing it the 'Peano' number from 'Peano_of_Type'.
370 lift_type
371 :: forall ty tys (root:: * -> *) h.
372 Lift_Type ty tys =>
373 ty root h -> tys root h
374 lift_type = lift_typeP (Proxy::Proxy (Peano_of_Type ty tys))
375
376 -- ** Type 'Unlift_Type'
377 -- | Apply 'Peano_of_Type' on 'Unlift_TypeP'.
378 type Unlift_Type ty tys
379 = Unlift_TypeP (Peano_of_Type ty tys) ty tys
380
381 -- *** Class 'Unlift_TypeP'
382 -- | Try to unlift a given type out of a given type stack including it,
383 -- by deconstructing the appropriate sequence of 'Type_Alt_Curr' and 'Type_Alt_Next'.
384 class Unlift_TypeP (p:: *) ty tys where
385 type_unliftN :: forall (root:: * -> *) h. Proxy p -> tys root h -> Maybe (ty root h)
386 instance Unlift_TypeP Zero curr curr where
387 type_unliftN _ = Just
388 instance Unlift_TypeP Zero curr (Type_Alt curr next) where
389 type_unliftN _ (Type_Alt_Curr x) = Just x
390 type_unliftN _ (Type_Alt_Next _) = Nothing
391 instance
392 Unlift_TypeP p other next =>
393 Unlift_TypeP (Succ p) other (Type_Alt curr next) where
394 type_unliftN _ (Type_Alt_Next x) = type_unliftN (Proxy::Proxy p) x
395 type_unliftN _ (Type_Alt_Curr _) = Nothing
396
397 -- | Convenient wrapper around 'type_unliftN',
398 -- passing it the 'Peano' number from 'Peano_of_Type'.
399 unlift_type
400 :: forall ty tys (root:: * -> *) h.
401 Unlift_Type ty tys =>
402 tys root h -> Maybe (ty root h)
403 unlift_type = type_unliftN (Proxy::Proxy (Peano_of_Type ty tys))
404
405 -- * Type 'Type_Type1'
406 -- | A type of kind @(k -> *)@.
407 data Type_Type1 px (root:: * -> *) h where
408 Type_Type1 :: px -> root a -> Type_Type1 px root ((Host1_of px) a)
409 type instance Root_of_Type (Type_Type1 px root) = root
410 type instance Error_of_Type ast (Type_Type1 px root) = No_Error_Type
411
412 instance Constraint_Type Eq (Type_Type1 (Proxy h1) root)
413 instance Constraint_Type Ord (Type_Type1 (Proxy h1) root)
414
415 instance -- Eq_Type
416 Eq_Type root =>
417 Eq_Type (Type_Type1 (Proxy h1) root) where
418 eq_type (Type_Type1 _px1 a1) (Type_Type1 _px2 a2)
419 | Just Refl <- a1 `eq_type` a2
420 = Just Refl
421 eq_type _ _ = Nothing
422 instance -- Eq_Type
423 Eq_Type root =>
424 Eq_Type (Type_Type1 EPeano root) where
425 eq_type (Type_Type1 p1 a1)
426 (Type_Type1 p2 a2)
427 | p1 == p2
428 , Just Refl <- a1 `eq_type` a2
429 = Just Refl
430 eq_type _ _ = Nothing
431 instance -- Eq
432 Eq_Type root =>
433 Eq (Type_Type1 (Proxy h1) root h) where
434 x == y = isJust $ eq_type x y
435 instance -- Eq
436 Eq_Type root =>
437 Eq (Type_Type1 EPeano root h) where
438 x == y = isJust $ eq_type x y
439 instance -- Eq_Type1
440 Eq_Type1 (Type_Type1 (Proxy t1) root) where
441 eq_type1 Type_Type1{} Type_Type1{}
442 = Just Refl
443 instance -- Show
444 String_from_Type (Type_Type1 px root) =>
445 Show (Type_Type1 px root h) where
446 show = string_from_type
447
448 -- ** Type family 'Host1_of'
449 type family Host1_of px :: * -> *
450 type instance Host1_of (Proxy h1) = h1
451
452 -- ** Type 'Lift_Type1'
453 data Lift_Type1 px tys
454 = Lift_Type1 ( forall (root:: * -> *) h
455 . Type_Type1 px root h -> tys root h
456 )
457
458 -- ** Type 'Unlift_Type1'
459 class Unlift_Type1 ty where
460 unlift_type1
461 :: forall (root:: * -> *) ret h.
462 ty root h
463 -> (forall (px:: *).
464 ( Type_Type1 px root h
465 , Lift_Type1 px ty
466 ) -> Maybe ret)
467 -> Maybe ret
468 unlift_type1 _ty _k = Nothing
469 instance Unlift_Type1 (Type_Type1 px) where
470 unlift_type1 ty k = k (ty, Lift_Type1 id)
471 instance -- Type_Alt
472 ( Unlift_Type1 curr
473 , Unlift_Type1 next
474 ) => Unlift_Type1 (Type_Alt curr next) where
475 unlift_type1 (Type_Alt_Curr ty) k =
476 fromMaybe Nothing $ unlift_type1 ty $ \(t, Lift_Type1 l) ->
477 Just $ k (t, Lift_Type1 $ Type_Alt_Curr . l)
478 unlift_type1 (Type_Alt_Next ty) k =
479 fromMaybe Nothing $ unlift_type1 ty $ \(t, Lift_Type1 l) ->
480 Just $ k (t, Lift_Type1 $ Type_Alt_Next . l)
481
482 -- * Type 'Type_Type2'
483 data Type_Type2 px (root:: * -> *) h where
484 Type_Type2
485 :: (Constraint2_of px) a b
486 => px -> root a -> root b
487 -> Type_Type2 px root ((Host2_of px) a b)
488 class Constraint2_Empty a b
489 instance Constraint2_Empty a b
490
491 type instance Root_of_Type (Type_Type2 px root) = root
492 type instance Error_of_Type ast (Type_Type2 px root) = No_Error_Type
493
494 instance -- Eq_Type
495 Eq_Type root =>
496 Eq_Type (Type_Type2 (Proxy h2) root) where
497 eq_type
498 (Type_Type2 _ arg1 res1)
499 (Type_Type2 _ arg2 res2)
500 | Just Refl <- arg1 `eq_type` arg2
501 , Just Refl <- res1 `eq_type` res2
502 = Just Refl
503 eq_type _ _ = Nothing
504 instance -- Eq_Type
505 Eq_Type root =>
506 Eq_Type (Type_Type2 EPeano root) where
507 eq_type (Type_Type2 p1 arg1 res1)
508 (Type_Type2 p2 arg2 res2)
509 | p1 == p2
510 , Just Refl <- arg1 `eq_type` arg2
511 , Just Refl <- res1 `eq_type` res2
512 = Just Refl
513 eq_type _ _ = Nothing
514 instance -- Eq
515 Eq_Type root =>
516 Eq (Type_Type2 (Proxy h2) root h) where
517 x == y = isJust $ x `eq_type` y
518 instance -- Eq
519 Eq_Type root =>
520 Eq (Type_Type2 EPeano root h) where
521 x == y = isJust $ x `eq_type` y
522 instance -- Show
523 ( String_from_Type root
524 , String_from_Type (Type_Type2 px root)
525 ) => Show (Type_Type2 px root h) where
526 show = string_from_type
527 instance Constraint_Type Eq (Type_Type2 px root)
528 instance Constraint_Type Ord (Type_Type2 px root)
529 instance Unlift_Type1 (Type_Type2 px) -- FIXME: should be doable
530 instance Eq_Type1 (Type_Type2 px root) -- FIXME: should be doable
531
532 -- ** Type 'Host2_of'
533 type family Host2_of px :: * -> * -> *
534 type instance Host2_of (Proxy h2) = h2
535
536 -- ** Type 'Constraint2_of'
537 type family Constraint2_of px :: (* -> * -> Constraint)
538
539 -- * Type family 'Is_Last_Type'
540 -- | Return whether a given type is the last one in a given type stack.
541 --
542 -- NOTE: each type parser uses this type family
543 -- when it encounters unsupported syntax:
544 -- to know if it is the last type parser component that will be tried
545 -- (and thus return 'Error_Type_Unsupported')
546 -- or if some other type parser component shall be tried
547 -- (and thus return 'Error_Type_Unsupported_here',
548 -- which is then handled accordingly by the 'Type_from' instance of 'Type_Alt').
549 type family Is_Last_Type (ty:: * -> *) (tys:: * -> *) :: Bool where
550 Is_Last_Type ty ty = 'True
551 Is_Last_Type ty (Type_Root tys) = Is_Last_Type ty (tys (Type_Root tys))
552 Is_Last_Type (ty root) (Type_Alt ty next root) = 'False
553 Is_Last_Type other (Type_Alt curr next root) = Is_Last_Type other (next root)
554
555 -- * Type 'Error_Type_Alt'
556 -- | Error type making an alternative between two error types.
557 data Error_Type_Alt curr next
558 = Error_Type_Alt_Curr curr
559 | Error_Type_Alt_Next next
560 deriving (Eq, Show)
561
562 -- ** Type 'Lift_Error_Type'
563 type Lift_Error_Type err errs
564 = Lift_Error_TypeP (Peano_of_Error_Type err errs) err errs
565
566 -- *** Type 'Peano_of_Error_Type'
567 -- | Return a 'Peano' number derived from the location
568 -- of a given error type within a given error type stack.
569 type family Peano_of_Error_Type (err:: *) (errs:: *) :: * where
570 Peano_of_Error_Type err err = Zero
571 Peano_of_Error_Type err (Error_Type_Alt err next) = Zero
572 Peano_of_Error_Type other (Error_Type_Alt curr next) = Succ (Peano_of_Error_Type other next)
573
574 -- *** Class 'Lift_Error_TypeP'
575 -- | Lift a given error type to the top of a given error type stack including it,
576 -- by constructing the appropriate sequence of 'Error_Type_Alt_Curr' and 'Error_Type_Alt_Next'.
577 class Lift_Error_TypeP (p:: *) err errs where
578 lift_error_typeP :: Proxy p -> err -> errs
579 instance Lift_Error_TypeP Zero curr curr where
580 lift_error_typeP _ = id
581 instance Lift_Error_TypeP Zero curr (Error_Type_Alt curr next) where
582 lift_error_typeP _ = Error_Type_Alt_Curr
583 instance
584 Lift_Error_TypeP p other next =>
585 Lift_Error_TypeP (Succ p) other (Error_Type_Alt curr next) where
586 lift_error_typeP _ = Error_Type_Alt_Next . lift_error_typeP (Proxy::Proxy p)
587
588 -- | Convenient wrapper around 'error_type_unliftN',
589 -- passing it the 'Peano' number from 'Peano_of_Error_Type'.
590 lift_error_type
591 :: forall err errs.
592 Lift_Error_Type err errs =>
593 err -> errs
594 lift_error_type = lift_error_typeP (Proxy::Proxy (Peano_of_Error_Type err errs))
595
596 -- ** Type 'Unlift_Error_Type'
597 -- | Apply 'Peano_of_Error_Type' on 'Error_Type_UnliftN'.
598 type Unlift_Error_Type ty tys
599 = Error_Type_UnliftN (Peano_of_Error_Type ty tys) ty tys
600
601 -- | Convenient wrapper around 'error_type_unliftN',
602 -- passing it the 'Peano' number from 'Peano_of_Error_Type'.
603 unlift_error_type
604 :: forall ty tys.
605 Unlift_Error_Type ty tys =>
606 tys -> Maybe ty
607 unlift_error_type = error_type_unliftN (Proxy::Proxy (Peano_of_Error_Type ty tys))
608
609 -- *** Class 'Error_Type_UnliftN'
610 -- | Try to unlift a given type error out of a given type error stack including it,
611 -- by deconstructing the appropriate sequence of 'Error_Type_Alt_Curr' and 'Error_Type_Alt_Next'.
612 class Error_Type_UnliftN (p:: *) ty tys where
613 error_type_unliftN :: Proxy p -> tys -> Maybe ty
614 instance Error_Type_UnliftN Zero curr curr where
615 error_type_unliftN _ = Just
616 instance Error_Type_UnliftN Zero curr (Error_Type_Alt curr next) where
617 error_type_unliftN _ (Error_Type_Alt_Curr x) = Just x
618 error_type_unliftN _ (Error_Type_Alt_Next _) = Nothing
619 instance
620 Error_Type_UnliftN p other next =>
621 Error_Type_UnliftN (Succ p) other (Error_Type_Alt curr next) where
622 error_type_unliftN _ (Error_Type_Alt_Next x) = error_type_unliftN (Proxy::Proxy p) x
623 error_type_unliftN _ (Error_Type_Alt_Curr _) = Nothing
624
625 -- ** Type 'Error_Type_Read'
626 -- | Common type errors.
627 data Error_Type ast
628 = Error_Type_Unsupported ast
629 -- ^ Given syntax is supported by none
630 -- of the type parser components
631 -- of the type stack.
632 | Error_Type_Unsupported_here ast
633 -- ^ Given syntax not supported by the current type parser component.
634 | Error_Type_Wrong_number_of_arguments ast Int
635 deriving (Eq, Show)
636
637 -- | Convenient wrapper around 'lift_error_type',
638 -- passing the type family boilerplate.
639 error_type
640 :: Lift_Error_Type (Error_Type ast)
641 (Error_of_Type ast (Root_of_Type ty))
642 => Proxy ty
643 -> Error_Type ast
644 -> Error_of_Type ast (Root_of_Type ty)
645 error_type _ = lift_error_type
646
647 error_type_unsupported
648 :: forall ast ty.
649 ( Implicit_HBool (Is_Last_Type ty (Root_of_Type ty))
650 , Lift_Error_Type (Error_Type ast) (Error_of_Type ast (Root_of_Type ty))
651 ) => Proxy ty -> ast
652 -> Error_of_Type ast (Root_of_Type ty)
653 error_type_unsupported ty ast =
654 case hbool :: HBool (Is_Last_Type ty (Root_of_Type ty)) of
655 HTrue -> error_type ty $ Error_Type_Unsupported ast
656 HFalse -> error_type ty $ Error_Type_Unsupported_here ast
657
658 -- * Class 'String_from_Type'
659 -- | Return a 'String' from a type.
660 class String_from_Type ty where
661 string_from_type :: ty h -> String
662
663 -- * Type 'Exists_Type'
664 -- | Existential data type wrapping the index of a type.
665 data Exists_Type ty
666 = forall h. Exists_Type (ty h)
667 instance -- Eq
668 Eq_Type ty =>
669 Eq (Exists_Type ty) where
670 Exists_Type xh == Exists_Type yh =
671 isJust $ xh `eq_type` yh
672 instance -- Show
673 String_from_Type ty =>
674 Show (Exists_Type ty) where
675 show (Exists_Type ty) = string_from_type ty
676
677 -- * Type 'Exists_Type1'
678 -- | Existential data type wrapping the index of a type1.
679 data Exists_Type1 ty
680 = forall h. Exists_Type1 (ty h -> ty h)
681
682 -- * Type 'Exists_Type_and_Repr'
683 data Exists_Type_and_Repr ty repr
684 = forall h.
685 Exists_Type_and_Repr (ty h) (repr h)
686
687 -- * Type family 'HBool'
688 -- | Host-type equality.
689 type family HEq x y :: Bool where
690 HEq x x = 'True
691 HEq x y = 'False
692 -- ** Type 'HBool'
693 -- | Boolean singleton.
694 data HBool b where
695 HTrue :: HBool 'True
696 HFalse :: HBool 'False
697 -- ** Class 'Implicit_HBool'
698 -- | Construct a host-term boolean singleton from a host-type boolean.
699 class Implicit_HBool b where hbool :: HBool b
700 instance Implicit_HBool 'True where hbool = HTrue
701 instance Implicit_HBool 'False where hbool = HFalse