1 {-# LANGUAGE DefaultSignatures #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE FlexibleInstances #-}
5 {-# LANGUAGE MultiParamTypeClasses #-}
6 {-# LANGUAGE Rank2Types #-}
7 {-# LANGUAGE ScopedTypeVariables #-}
8 {-# LANGUAGE TypeFamilies #-}
9 {-# LANGUAGE TypeOperators #-}
10 {-# LANGUAGE UndecidableInstances #-}
11 module Language.Symantic.Type.Type1 where
13 import Data.Maybe (isJust, fromMaybe)
15 import Data.Type.Equality ((:~:)(Refl))
17 import Language.Symantic.Lib.Data.Peano
18 import Language.Symantic.Lib.Data.Bool
19 import Language.Symantic.Type.Root
20 import Language.Symantic.Type.Alt
21 import Language.Symantic.Type.Error
22 import Language.Symantic.Type.Type0
25 -- | A type of kind @(* -> *)@.
26 data Type1 px (root:: * -> *) h where
28 -> Type1 px root ((Host1_of px) a)
30 type instance Root_of_Type (Type1 px root) = root
31 type instance Error_of_Type ast (Type1 px root) = No_Error_Type
35 Type0_Eq (Type1 (Proxy h1) root) where
36 type0_eq (Type1 _px1 a1) (Type1 _px2 a2)
37 | Just Refl <- a1 `type0_eq` a2
39 type0_eq _ _ = Nothing
42 Type0_Eq (Type1 EPeano root) where
43 type0_eq (Type1 p1 a1)
46 , Just Refl <- a1 `type0_eq` a2
48 type0_eq _ _ = Nothing
51 Eq (Type1 (Proxy h1) root h) where
52 x == y = isJust $ type0_eq x y
55 Eq (Type1 EPeano root h) where
56 x == y = isJust $ type0_eq x y
58 Type1_Eq (Type1 (Proxy t1) root) where
59 type1_eq Type1{} Type1{}
62 String_from_Type (Type1 px root) =>
63 Show (Type1 px root h) where
64 show = string_from_type
66 -- | Inject a 'Type1' within a root type.
69 Type_Root_Lift (Type1 (Proxy h1)) root
70 => root a -> root (h1 a)
71 type1 = type_root_lift . Type1 (Proxy::Proxy h1)
73 -- ** Type family 'Host1_of'
74 type family Host1_of px :: * -> *
75 type instance Host1_of (Proxy h1) = h1
78 -- | Test two type constructors for equality,
79 -- returning an Haskell type-level proof
80 -- of the equality when it holds.
81 class Type1_Eq (ty:: * -> *) where
82 type1_eq :: forall h1 h2 a1 a2. ty (h1 a1) -> ty (h2 a2) -> Maybe (h1 :~: h2)
83 type1_eq = error "type1_eq"
85 Type1_Eq (ty (Type_Root ty)) =>
86 Type1_Eq (Type_Root ty) where
87 type1_eq (Type_Root x) (Type_Root y) = x `type1_eq` y
89 ( Type1_Eq (curr root)
90 , Type1_Eq (next root)
91 ) => Type1_Eq (Type_Alt curr next root) where
92 type1_eq (Type_Alt_Curr x) (Type_Alt_Curr y) = x `type1_eq` y
93 type1_eq (Type_Alt_Next x) (Type_Alt_Next y) = x `type1_eq` y
94 type1_eq _ _ = Nothing
95 instance -- Type0 (Proxy h0)
96 Type1_Eq (Type0 (Proxy h0) root)
98 -- * Class 'Type1_From'
99 -- | Parse given @ast@ into a 'Root_of_Type' constructor,
100 -- or return an 'Error_of_Type'.
101 class Type1_From ast (ty:: * -> *) where
105 -> (forall (h1:: * -> *). Proxy h1
106 -> (forall h. Root_of_Type ty h -> Root_of_Type ty (h1 h))
107 -> Either (Error_of_Type ast (Root_of_Type ty)) ret)
108 -> Either (Error_of_Type ast (Root_of_Type ty)) ret
109 default type1_from ::
110 ( Error_Type_Lift (Error_Type ast) (Error_of_Type ast (Root_of_Type ty))
111 , IBool (Is_Last_Type ty (Root_of_Type ty))
114 -> (forall (h1:: * -> *). Proxy h1
115 -> (forall h. Root_of_Type ty h -> Root_of_Type ty (h1 h))
116 -> Either (Error_of_Type ast (Root_of_Type ty)) ret)
117 -> Either (Error_of_Type ast (Root_of_Type ty)) ret
118 type1_from ty ast _k =
119 Left $ error_type_unsupported ty ast
120 instance -- Type_Root
121 ( Type0_Eq (Type_Root ty)
122 , Type1_From ast (ty (Type_Root ty))
123 , Root_of_Type (ty (Type_Root ty)) ~ Type_Root ty
124 ) => Type1_From ast (Type_Root ty) where
125 type1_from _ty = type1_from (Proxy::Proxy (ty (Type_Root ty)))
128 ( Type0_Eq (curr root)
129 , Type1_From ast (curr root)
130 , Type1_From ast (next root)
131 , Root_of_Type (curr root) ~ root
132 , Root_of_Type (next root) ~ root
133 , Error_Type_Unlift (Error_Type ast) (Error_of_Type ast root)
134 ) => Type1_From ast (Type_Alt curr next root) where
135 type1_from _ty ast k =
136 case type1_from (Proxy::Proxy (curr root)) ast (\f ty -> Right $ k f ty) of
139 case error_type_unlift err of
140 Just (Error_Type_Unsupported_here (_::ast)) ->
141 type1_from (Proxy::Proxy (next root)) ast k
144 -- ** Type 'Type1_Lift'
145 data Type1_Lift px root tys
146 = Type1_Lift ( forall {-(root:: * -> *)-} h
147 . Type1 px root h -> tys root h
150 -- ** Type 'Type1_Unlift'
151 class Type1_Unlift ty where
153 :: forall (root:: * -> *) ret h.
157 , Type1_Lift px root ty
160 type1_unlift _ty _k = Nothing
161 instance Type1_Unlift (Type1 px) where
162 type1_unlift ty k = k (ty, Type1_Lift id)
166 ) => Type1_Unlift (Type_Alt curr next) where
167 type1_unlift (Type_Alt_Curr ty) k =
168 fromMaybe Nothing $ type1_unlift ty $ \(t, Type1_Lift l) ->
169 Just $ k (t, Type1_Lift $ Type_Alt_Curr . l)
170 type1_unlift (Type_Alt_Next ty) k =
171 fromMaybe Nothing $ type1_unlift ty $ \(t, Type1_Lift l) ->
172 Just $ k (t, Type1_Lift $ Type_Alt_Next . l)
174 Type1_Unlift (Type0 px)
176 -- * Type 'Exists_Type1'
177 -- | Existential data type wrapping the index of a 'Type1'.
179 = forall h. Exists_Type1 (ty h -> ty h)