1 {-# LANGUAGE DataKinds #-}
2 {-# LANGUAGE PolyKinds #-}
3 {-# LANGUAGE ConstraintKinds #-}
4 {-# LANGUAGE FlexibleContexts #-}
5 {-# LANGUAGE FlexibleInstances #-}
7 {-# LANGUAGE MultiParamTypeClasses #-}
8 {-# LANGUAGE ScopedTypeVariables #-}
9 {-# LANGUAGE TypeFamilies #-}
10 {-# LANGUAGE TypeOperators #-}
11 {-# LANGUAGE UndecidableInstances #-}
12 {-# OPTIONS_GHC -fconstraint-solver-iterations=0 #-}
13 module Language.Symantic.Typing.Constraint where
15 import Data.Maybe (fromMaybe)
17 import Data.Type.Equality
19 import Language.Symantic.Typing.Kind
20 import Language.Symantic.Typing.Constant
21 import Language.Symantic.Typing.Type
24 -- | Captures the proof of a 'Constraint'
25 -- (and its dictionary for a type class):
26 -- pattern matching on the 'Con' constructor
27 -- brings the 'Constraint' into scope.
31 -- * Type family 'Consts_imported_by'
32 -- | Return the /type constant/s that a given /type constant/
33 -- wants to be part of the final list of /type constants/.
34 type family Consts_imported_by (c::k) :: [*]
35 type instance Consts_imported_by [] =
45 type instance Consts_imported_by (->) =
51 type instance Consts_imported_by Applicative = '[]
52 type instance Consts_imported_by Bool =
58 type instance Consts_imported_by Bounded = '[]
59 type instance Consts_imported_by Eq = '[]
60 type instance Consts_imported_by Enum = '[]
61 type instance Consts_imported_by Foldable = '[]
62 type instance Consts_imported_by Functor = '[]
63 type instance Consts_imported_by Int =
72 type instance Consts_imported_by Integer =
80 type instance Consts_imported_by Integral =
84 type instance Consts_imported_by IO =
89 type instance Consts_imported_by Maybe =
98 type instance Consts_imported_by Monad = '[]
99 type instance Consts_imported_by Monoid = '[]
100 type instance Consts_imported_by Num = '[]
101 type instance Consts_imported_by Ord = '[]
102 type instance Consts_imported_by Real = '[]
103 type instance Consts_imported_by Traversable = '[]
106 -- | Convenient type synonym wrapping 'Proj_ConR'
107 -- to initiate its recursion.
108 type Proj_Con cs = Proj_ConR cs cs
110 -- | Project the 'Constraint' indexed by the given 'Type'
111 -- onto its proof, captured by 'Con' when it holds.
113 :: forall cs q. Proj_Con cs
115 -> Maybe (Con (UnProxy q))
116 proj_con = proj_conR (Proxy::Proxy cs)
118 -- ** Class 'Proj_ConR'
119 -- | Intermediate type class to construct an instance of 'Proj_Con'
120 -- from many instances of 'Proj_ConC', one for each item of @cs@.
122 -- * @cs@: starting list of /type constants/.
123 -- * @rs@: remaining list of /type constants/.
124 class Proj_ConR cs rs where
125 proj_conR :: Proxy rs -> Type cs 'KiCon q -> Maybe (Con (UnProxy q))
126 proj_conR _rs _q = Nothing
128 -- | Test whether @c@ handles the work of 'Proj_Con' or not,
129 -- or recurse on @rs@, preserving the starting list of /type constants/.
133 ) => Proj_ConR cs (c ': rs) where
135 proj_conR (Proxy::Proxy rs) q `fromMaybe`
136 proj_conC (Proxy::Proxy c) q
137 -- | End the recursion.
138 instance Proj_ConR cs '[]
140 -- ** Class 'Proj_ConC'
141 -- | Handle the work of 'Proj_Con' for a given /type constant/ @c@,
142 -- that is: maybe it handles the given 'Constraint',
143 -- and if so, maybe the 'Constraint' holds.
144 class Proj_ConC cs c where
145 proj_conC :: Proxy c -> Type cs 'KiCon q -> Maybe (Maybe (Con (UnProxy q)))
146 proj_conC _c _q = Nothing
149 ( Proj_Const cs (Proxy [])
150 , Proj_Consts cs (Consts_imported_by [])
152 ) => Proj_ConC cs (Proxy []) where
153 proj_conC _ (TyConst q :$ TyConst c)
154 | Just Refl <- proj_const c (Proxy::Proxy [])
156 _ | Just Refl <- proj_const q (Proxy::Proxy Applicative) -> Just Con
157 | Just Refl <- proj_const q (Proxy::Proxy Foldable) -> Just Con
158 | Just Refl <- proj_const q (Proxy::Proxy Functor) -> Just Con
159 | Just Refl <- proj_const q (Proxy::Proxy Monad) -> Just Con
160 | Just Refl <- proj_const q (Proxy::Proxy Traversable) -> Just Con
162 proj_conC _ (t@(TyConst q) :$ (TyConst c :$ a))
163 | Just Refl <- proj_const c (Proxy::Proxy [])
165 _ | Just Refl <- proj_const q (Proxy::Proxy Eq)
166 , Just Con <- proj_con (t :$ a) -> Just Con
167 | Just Refl <- proj_const q (Proxy::Proxy Monoid)
168 , Just Con <- proj_con (t :$ a) -> Just Con
169 | Just Refl <- proj_const q (Proxy::Proxy Ord)
170 , Just Con <- proj_con (t :$ a) -> Just Con
172 proj_conC _c _q = Nothing
174 ( Proj_Const cs (Proxy (->))
175 , Proj_Consts cs (Consts_imported_by (->))
177 ) => Proj_ConC cs (Proxy (->)) where
178 proj_conC _ (TyConst q :$ (TyConst c :$ _r))
179 | Just Refl <- proj_const c (Proxy::Proxy (->))
181 _ | Just Refl <- proj_const q (Proxy::Proxy Functor) -> Just Con
182 | Just Refl <- proj_const q (Proxy::Proxy Applicative) -> Just Con
183 | Just Refl <- proj_const q (Proxy::Proxy Monad) -> Just Con
185 proj_conC _ (t@(TyConst q) :$ (TyConst c :$ _a :$ b))
186 | Just Refl <- proj_const c (Proxy::Proxy (->))
188 _ | Just Refl <- proj_const q (Proxy::Proxy Monoid)
189 , Just Con <- proj_con (t :$ b) -> Just Con
191 proj_conC _c _q = Nothing
192 instance -- Applicative
193 ( Proj_Const cs (Proxy Applicative)
194 , Proj_Consts cs (Consts_imported_by Applicative)
195 ) => Proj_ConC cs (Proxy Applicative)
197 ( Proj_Const cs (Proxy Bool)
198 , Proj_Consts cs (Consts_imported_by Bool)
199 ) => Proj_ConC cs (Proxy Bool) where
200 proj_conC _ (TyConst q :$ TyConst c)
201 | Just Refl <- proj_const c (Proxy::Proxy Bool)
203 _ | Just Refl <- proj_const q (Proxy::Proxy Bounded) -> Just Con
204 | Just Refl <- proj_const q (Proxy::Proxy Enum) -> Just Con
205 | Just Refl <- proj_const q (Proxy::Proxy Eq) -> Just Con
206 | Just Refl <- proj_const q (Proxy::Proxy Ord) -> Just Con
208 proj_conC _c _q = Nothing
210 ( Proj_Const cs (Proxy Bounded)
211 , Proj_Consts cs (Consts_imported_by Bounded)
212 ) => Proj_ConC cs (Proxy Bounded)
214 ( Proj_Const cs (Proxy Enum)
215 , Proj_Consts cs (Consts_imported_by Enum)
216 ) => Proj_ConC cs (Proxy Enum)
218 ( Proj_Const cs (Proxy Eq)
219 , Proj_Consts cs (Consts_imported_by Eq)
220 ) => Proj_ConC cs (Proxy Eq)
222 ( Proj_Const cs (Proxy Foldable)
223 , Proj_Consts cs (Consts_imported_by Foldable)
224 ) => Proj_ConC cs (Proxy Foldable)
226 ( Proj_Const cs (Proxy Functor)
227 , Proj_Consts cs (Consts_imported_by Functor)
228 ) => Proj_ConC cs (Proxy Functor)
230 ( Proj_Const cs (Proxy Int)
231 , Proj_Consts cs (Consts_imported_by Int)
232 ) => Proj_ConC cs (Proxy Int) where
233 proj_conC _ (TyConst q :$ TyConst c)
234 | Just Refl <- proj_const c (Proxy::Proxy Int)
236 _ | Just Refl <- proj_const q (Proxy::Proxy Bounded) -> Just Con
237 | Just Refl <- proj_const q (Proxy::Proxy Enum) -> Just Con
238 | Just Refl <- proj_const q (Proxy::Proxy Eq) -> Just Con
239 | Just Refl <- proj_const q (Proxy::Proxy Integral) -> Just Con
240 | Just Refl <- proj_const q (Proxy::Proxy Num) -> Just Con
241 | Just Refl <- proj_const q (Proxy::Proxy Ord) -> Just Con
242 | Just Refl <- proj_const q (Proxy::Proxy Real) -> Just Con
244 proj_conC _c _q = Nothing
246 ( Proj_Const cs (Proxy Integer)
247 , Proj_Consts cs (Consts_imported_by Integer)
248 ) => Proj_ConC cs (Proxy Integer) where
249 proj_conC _ (TyConst q :$ TyConst c)
250 | Just Refl <- proj_const c (Proxy::Proxy Integer)
252 _ | Just Refl <- proj_const q (Proxy::Proxy Enum) -> Just Con
253 | Just Refl <- proj_const q (Proxy::Proxy Eq) -> Just Con
254 | Just Refl <- proj_const q (Proxy::Proxy Integral) -> Just Con
255 | Just Refl <- proj_const q (Proxy::Proxy Num) -> Just Con
256 | Just Refl <- proj_const q (Proxy::Proxy Ord) -> Just Con
257 | Just Refl <- proj_const q (Proxy::Proxy Real) -> Just Con
259 proj_conC _c _q = Nothing
261 ( Proj_Const cs (Proxy Integral)
262 , Proj_Consts cs (Consts_imported_by Integral)
263 ) => Proj_ConC cs (Proxy Integral)
265 ( Proj_Const cs (Proxy IO)
266 , Proj_Consts cs (Consts_imported_by IO)
267 ) => Proj_ConC cs (Proxy IO) where
268 proj_conC _ (TyConst q :$ TyConst c)
269 | Just Refl <- proj_const c (Proxy::Proxy IO)
271 _ | Just Refl <- proj_const q (Proxy::Proxy Applicative) -> Just Con
272 | Just Refl <- proj_const q (Proxy::Proxy Functor) -> Just Con
273 | Just Refl <- proj_const q (Proxy::Proxy Monad) -> Just Con
275 proj_conC _c _q = Nothing
277 ( Proj_Const cs (Proxy Maybe)
278 , Proj_Consts cs (Consts_imported_by Maybe)
280 ) => Proj_ConC cs (Proxy Maybe) where
281 proj_conC _ (TyConst q :$ TyConst c)
282 | Just Refl <- proj_const c (Proxy::Proxy Maybe)
284 _ | Just Refl <- proj_const q (Proxy::Proxy Applicative) -> Just Con
285 | Just Refl <- proj_const q (Proxy::Proxy Foldable) -> Just Con
286 | Just Refl <- proj_const q (Proxy::Proxy Functor) -> Just Con
287 | Just Refl <- proj_const q (Proxy::Proxy Monad) -> Just Con
288 | Just Refl <- proj_const q (Proxy::Proxy Traversable) -> Just Con
290 proj_conC _ (t@(TyConst q) :$ (TyConst c :$ a))
291 | Just Refl <- proj_const c (Proxy::Proxy Maybe)
293 _ | Just Refl <- proj_const q (Proxy::Proxy Eq)
294 , Just Con <- proj_con (t :$ a) -> Just Con
295 | Just Refl <- proj_const q (Proxy::Proxy Monoid)
296 , Just Con <- proj_con (t :$ a) -> Just Con
298 proj_conC _c _q = Nothing
300 ( Proj_Const cs (Proxy Monad)
301 , Proj_Consts cs (Consts_imported_by Monad)
302 ) => Proj_ConC cs (Proxy Monad)
304 ( Proj_Const cs (Proxy Monoid)
305 , Proj_Consts cs (Consts_imported_by Monoid)
306 ) => Proj_ConC cs (Proxy Monoid)
308 ( Proj_Const cs (Proxy Num)
309 , Proj_Consts cs (Consts_imported_by Num)
310 ) => Proj_ConC cs (Proxy Num)
312 ( Proj_Const cs (Proxy Ord)
313 , Proj_Consts cs (Consts_imported_by Ord)
314 ) => Proj_ConC cs (Proxy Ord)
316 ( Proj_Const cs (Proxy Real)
317 , Proj_Consts cs (Consts_imported_by Real)
318 ) => Proj_ConC cs (Proxy Real)
319 instance -- Traversable
320 ( Proj_Const cs (Proxy Traversable)
321 , Proj_Consts cs (Consts_imported_by Traversable)
322 ) => Proj_ConC cs (Proxy Traversable)