update GHC.HetMet.CodeTypes using *->*->* as the kind of environment classifiers
[ghc-base.git] / GHC / HetMet / CodeTypes.hs
1 {-# OPTIONS -XModalTypes -XMultiParamTypeClasses -XKindSignatures #-}
2 module GHC.HetMet.CodeTypes (
3   hetmet_brak,
4   hetmet_esc,
5   hetmet_csp,
6   GuestIntegerLiteral, guestIntegerLiteral,
7   GuestStringLiteral, guestStringLiteral,
8   GuestCharLiteral, guestCharLiteral,
9   GuestLanguageMult, <[ (*) ]>,
10   GuestLanguageAdd,  <[ (+) ]>,
11   GuestLanguageSub,  <[ (-) ]>, <[ negate ]>,
12   GuestLanguageFromInteger, <[ fromInteger ]>,
13   GuestLanguageBool, <[ (||) ]>, <[ (&&) ]>, <[ true ]>, <[ false ]>, <[ ifThenElse ]>
14 ) where
15 import Prelude (Integer, String, Char, Bool, error)
16 import GHC.HetMet.GArrow
17
18 hetmet_brak :: forall (c :: * -> * -> *). forall a. a -> <[a]>@c
19 hetmet_brak = Prelude.error "hetmet_brak should never be evaluated; did you forget to compile with -fcoqpass?"
20
21 hetmet_esc  :: forall (c :: * -> * -> *). forall a. <[a]>@c -> a
22 hetmet_esc = Prelude.error "hetmet_esc should never be evaluated; did you forget to compile with -fcoqpass?"
23
24 hetmet_csp :: forall (c :: * -> * -> *). forall a. a -> a
25 hetmet_csp = Prelude.error "hetmet_csp should never be evaluated; did you forget to compile with -fcoqpass?"
26
27 {-
28 -- After the flattening pass the argument and result types of this
29 -- function are identical (for any instantiation), so the flattener
30 -- simply turns it into the identity function.  Its only purpose is to
31 -- act as a "safe type cast" during pre-flattening
32 -- type-inference/checking:
33 hetmet_flatten ::
34    forall g.
35     GArrow     g (**) =>
36     GArrowDrop g (**) =>
37     GArrowCopy g (**) =>
38     GArrowSwap g (**) =>
39     GArrowLoop g (**) =>
40       forall x y.
41          <[ x -> y ]>@g
42          ->
43          (g x y)
44 hetmet_flatten _ = Prelude.error "hetmet_flatten should never be evaluated; did you forget to compile with -fcoqpass?"
45 -}
46
47
48 -- FIXME: move these and the three above to "prim" or something like that.
49
50 -- Technically these functions ought to be invoked *during
51 -- compilation*; in the future I would like to use Template Haskell to
52 -- do that.
53 class GuestIntegerLiteral c where
54   guestIntegerLiteral :: Integer -> <[ Integer ]>@c
55 class GuestStringLiteral c where
56   guestStringLiteral :: String -> <[ String ]>@c
57 class GuestCharLiteral c where
58   guestCharLiteral :: Char -> <[ Char ]>@c
59
60
61 class GuestLanguageConstant c t where
62   guestLanguageConstant :: t -> <[ t ]>@c
63
64 -- Note that stringwise-identical identifiers at different syntactic
65 -- depths are different identifiers; for this reason the operators
66 -- below can have a different type at syntactical depth 1 than at
67 -- syntactical depth 0.
68
69 class GuestLanguageMult c t where
70   <[ (*)    ]> :: <[ t -> t -> t ]>@c
71
72 class GuestLanguageAdd c t where
73   <[ (+)    ]> :: <[ t -> t -> t ]>@c
74
75 class GuestLanguageSub c t where
76   <[ (-)    ]> :: <[ t -> t -> t ]>@c
77   <[ negate ]> :: <[ t -> t      ]>@c   -- used for unary (-)
78
79 class GuestLanguageFromInteger c t where
80   <[ fromInteger ]> :: <[ Integer -> t ]>@c
81
82 class GuestLanguageBool c where
83   <[ (||) ]>       :: <[ Bool -> Bool -> Bool ]>@c
84   <[ (&&) ]>       :: <[ Bool -> Bool -> Bool ]>@c
85   <[ true ]>       :: <[ Bool ]>@c
86   <[ false ]>      :: <[ Bool ]>@c
87   <[ ifThenElse ]> :: <[ Bool -> t -> t -> t ]>@c
88
89 -- For heterogeneous metaprogramming, the meaning of "running" a
90 -- program is fairly ambiguous, and moreover is highly sensitive to
91 -- which subclasses of GuestLanguage the expression assumes it is
92 -- dealing with.  For example, in homogeneous metaprogramming, "run"
93 -- has this type:
94 --
95 --  ga_run :: forall a. (forall c. <[a]>@c) -> a
96 --
97 -- However, an expression which uses, say (*) at level 1 will never
98 -- be able to be passed to this expression, since
99 --
100 --   square :: forall c t. GuestLanguageMult ct => <[t]>@c -> <[t]>@c
101 --   square x = <[ ~~x * ~~x ]>
102 --
103
104 -- So even though this expression is polymorphic in the environment
105 -- classifier "c", it isn't "polymorphic enough".  This isn't merely a
106 -- technical obstacle -- the more features you assume the guest
107 -- language has, the more work the "run" implementation is obligated
108 -- to perform, and the type system must track that obligation.
109 --
110 -- The upshot is that we can define special-purpose "run" classes such as:
111 --
112 --   class GuestLanguageRunMult t where
113 --     ga_runMult :: forall a. (forall c. GuestLanguageMult c t => <[a]>@c) -> a
114 --
115 -- Any implementation of this class will need to know how to interpret
116 -- the (*) operator.  Unfortunately, to my knowledge, there is no way
117 -- to quantify over type classes in the Haskell type system, which is
118 -- what we would need to define a type-class-indexed version of the
119 -- GuestLanguageRun class; if we could do that, then we would have:
120 --
121 --   class GuestLanguageRun ( t ::: * -> TYPECLASS ) where
122 --     ga_runMult :: forall a. (forall c. TYPECLASS c => <[a]>@c) -> a
123 --
124 -- It might be possible to pull this of using type families; I need to
125 -- look into that.
126