1 {-# LANGUAGE ConstraintKinds #-}
2 {-# LANGUAGE PolyKinds #-}
3 module Language.Symantic.Typing.Family where
5 import Control.Applicative ((<|>))
7 import Data.Text (Text)
9 import Language.Symantic.Typing.Type
11 -- * Type family 'Fam'
12 -- | Apply the /type family/ selected by @fam@
13 -- to a list of types (within a 'Proxy').
14 type family Fam fam (hs::[*]) :: *
20 -- | Convenient type synonym wrapping 'Proj_FamR'
21 -- to initiate its recursion.
22 type Proj_Fam cs = Proj_FamR cs cs
24 -- | Project the 'Constraint' indexed by the given 'Type'
25 -- onto its proof, captured by 'Con' when it holds.
27 :: forall fam cs hs. Proj_Fam cs fam
28 => fam -> Types cs hs -> Maybe (Type cs (Fam fam hs))
29 proj_fam = proj_famR (Proxy @cs)
31 -- ** Class 'Proj_FamR'
32 -- | Intermediate type class to construct an instance of 'Proj_Fam'
33 -- from many instances of 'Proj_FamC', one for each item of @cs@.
35 -- * @cs@: starting list of /type constants/.
36 -- * @rs@: remaining list of /type constants/.
37 class Proj_FamR (cs::[*]) (rs::[*]) fam where
39 :: Proxy rs -> fam -> Types cs hs
40 -> Maybe (Type cs (Fam fam hs))
41 proj_famR _rs _fam _ty = Nothing
43 -- | Test whether @c@ handles the work of 'Proj_Fam' or not,
44 -- or recurse on @rs@, preserving the starting list of /type constants/.
48 ) => Proj_FamR cs (Proxy c ': rs) fam where
49 proj_famR _rs fam typ =
50 proj_famC (Proxy @c) fam typ <|>
51 proj_famR (Proxy @rs) fam typ
52 -- | End the recursion.
53 instance Proj_FamR cs '[] fam
55 -- ** Class 'Proj_FamC'
56 -- | Handle the work of 'Proj_Fam' for a given /type family/ @fam@ and /type constant/ @c@,
57 -- that is: maybe it handles the given /type family/,
58 -- and if so, maybe the /type family/ has an instance for the given 'Type'.
59 class Proj_FamC cs fam (c::kc) where
61 :: Proxy c -> fam -> Types cs hs
62 -> Maybe (Type cs (Fam fam hs))
63 proj_famC _c _fam _ty = Nothing