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
27 Type1 :: px -> root a -> Type1 px root ((Host1_of px) a)
29 type instance Root_of_Type (Type1 px root) = root
30 type instance Error_of_Type ast (Type1 px root) = No_Error_Type
34 Type0_Eq (Type1 (Proxy h1) root) where
35 type0_eq (Type1 _px1 a1) (Type1 _px2 a2)
36 | Just Refl <- a1 `type0_eq` a2
38 type0_eq _ _ = Nothing
41 Type0_Eq (Type1 EPeano root) where
42 type0_eq (Type1 p1 a1)
45 , Just Refl <- a1 `type0_eq` a2
47 type0_eq _ _ = Nothing
50 Eq (Type1 (Proxy h1) root h) where
51 x == y = isJust $ type0_eq x y
54 Eq (Type1 EPeano root h) where
55 x == y = isJust $ type0_eq x y
57 Type1_Eq (Type1 (Proxy t1) root) where
58 type1_eq Type1{} Type1{} = Just Refl
60 String_from_Type (Type1 px root) =>
61 Show (Type1 px root h) where
62 show = string_from_type
64 -- | Inject a 'Type1' within a root type.
67 Type_Root_Lift (Type1 (Proxy h1)) root
68 => root a -> root (h1 a)
69 type1 = type_root_lift . Type1 (Proxy::Proxy h1)
71 -- ** Type family 'Host1_of'
72 type family Host1_of px :: * -> *
73 type instance Host1_of (Proxy h1) = h1
76 -- | Test two type constructors for equality,
77 -- returning an Haskell type-level proof
78 -- of the equality when it holds.
79 class Type1_Eq (ty:: * -> *) where
80 type1_eq :: forall h1 h2 a1 a2. ty (h1 a1) -> ty (h2 a2) -> Maybe (h1 :~: h2)
81 type1_eq = error "type1_eq"
83 Type1_Eq (ty (Type_Root ty)) =>
84 Type1_Eq (Type_Root ty) where
85 type1_eq (Type_Root x) (Type_Root y) = x `type1_eq` y
87 ( Type1_Eq (curr root)
88 , Type1_Eq (next root)
89 ) => Type1_Eq (Type_Alt curr next root) where
90 type1_eq (Type_Alt_Curr x) (Type_Alt_Curr y) = x `type1_eq` y
91 type1_eq (Type_Alt_Next x) (Type_Alt_Next y) = x `type1_eq` y
92 type1_eq _ _ = Nothing
93 instance -- Type0 (Proxy h0)
94 Type1_Eq (Type0 (Proxy h0) root)
96 -- * Class 'Type1_From'
97 -- | Parse given @ast@ into a 'Root_of_Type' constructor,
98 -- or return an 'Error_of_Type'.
99 class Type1_From ast (ty:: * -> *) where
103 -> (forall (h1:: * -> *). Proxy h1
104 -> (forall h. Root_of_Type ty h -> Root_of_Type ty (h1 h))
105 -> Either (Error_of_Type ast (Root_of_Type ty)) ret)
106 -> Either (Error_of_Type ast (Root_of_Type ty)) ret
107 default type1_from ::
108 ( Error_Type_Lift (Error_Type ast) (Error_of_Type ast (Root_of_Type ty))
109 , IBool (Is_Last_Type ty (Root_of_Type ty))
112 -> (forall (h1:: * -> *). Proxy h1
113 -> (forall h. Root_of_Type ty h -> Root_of_Type ty (h1 h))
114 -> Either (Error_of_Type ast (Root_of_Type ty)) ret)
115 -> Either (Error_of_Type ast (Root_of_Type ty)) ret
116 type1_from ty ast _k =
117 Left $ error_type_unsupported ty ast
118 instance -- Type_Root
119 ( Type0_Eq (Type_Root ty)
120 , Type1_From ast (ty (Type_Root ty))
121 , Root_of_Type (ty (Type_Root ty)) ~ Type_Root ty
122 ) => Type1_From ast (Type_Root ty) where
123 type1_from _ty = type1_from (Proxy::Proxy (ty (Type_Root ty)))
126 ( Type0_Eq (curr root)
127 , Type1_From ast (curr root)
128 , Type1_From ast (next root)
129 , Root_of_Type (curr root) ~ root
130 , Root_of_Type (next root) ~ root
131 , Error_Type_Unlift (Error_Type ast) (Error_of_Type ast root)
132 ) => Type1_From ast (Type_Alt curr next root) where
133 type1_from _ty ast k =
134 case type1_from (Proxy::Proxy (curr root)) ast (\f ty -> Right $ k f ty) of
137 case error_type_unlift err of
138 Just (Error_Type_Unsupported_here (_::ast)) ->
139 type1_from (Proxy::Proxy (next root)) ast k
142 -- ** Type 'Type1_Lift'
143 data Type1_Lift px root tys
144 = Type1_Lift (forall h. Type1 px root h -> tys root h)
146 -- ** Type 'Type1_Unlift'
147 class Type1_Unlift ty where
149 :: forall (root:: * -> *) ret h.
153 , Type1_Lift px root ty
156 instance Type1_Unlift (Type0 px) where
157 type1_unlift _ty _k = Nothing
158 instance Type1_Unlift (Type1 px) where
159 type1_unlift ty k = k (ty, Type1_Lift id)
163 ) => Type1_Unlift (Type_Alt curr next) where
164 type1_unlift (Type_Alt_Curr ty) k =
165 fromMaybe Nothing $ type1_unlift ty $ \(t, Type1_Lift l) ->
166 Just $ k (t, Type1_Lift $ Type_Alt_Curr . l)
167 type1_unlift (Type_Alt_Next ty) k =
168 fromMaybe Nothing $ type1_unlift ty $ \(t, Type1_Lift l) ->
169 Just $ k (t, Type1_Lift $ Type_Alt_Next . l)
171 -- * Type 'Exists_Type1'
172 -- | Existential data type wrapping the index of a 'Type1'.
174 = forall h. Exists_Type1 (ty h -> ty h)