[Template-haskell] Re: template-haskell
Keean Schupke
k.schupke at imperial.ac.uk
Mon Feb 28 07:20:36 EST 2005
Thanks for the info... some comments:
Simon Peyton-Jones wrote:
>Yes, quoted code is typechecked. The right way to express the result
>would be for the TH implementation to make a data structure (Exp, Decl
>etc) representing the *typed* code, and then do_something could look at
>those types. This does come up quite regularly.
>
>So why have I not done it?
>
>(a) It needs some design work on TH syntax. It must be able to express
>typed code (produced by quotes) and untyped code (produced by the user's
>program)
>
>
TH already has type syntax, as I can examine:
[|
f :: Num a => a -> a
f a = a + 1
|]
So I am not sure I understand which bit of syntax is missing?
>(b) The types are only partly there. For example
> \x -> $(do_something [| \y -> x |])
>Here the (\y->x) doesn't know the full type for x. Indeed just, x's
>type may not be fully worked out by the time do_something runs. For
>example we might have
> \x -> ($(do_something [| \y -> x |]), x::Int)
>Eventually we know that x::Int, but perhaps not when we run
>do_something. It depends on the order in which the type checker does
>things.
>
>This is a pretty nasty problem because the semantics of TH would then
>depend on order of type checking etc.
>
>
Actually I would be happy with the best guess so far without
going outside the current context, so for the above:
\x -> ($(do_something [| \y -> x |]), x::Int)
The type could be " a -> a " ... IE just looking at the anonymous
functions it is fully polymorphic.
You could veiw this as the most specific type available without
information from outside the meta-quote, which is the only definition
that makes sense to me at the moment.
>(c) When type checking a splice, should we ignore types in the TH code,
>or respect them?
>
The easyest answer is do not put the types in. If TH creates two
data structures, one with the code as written in the meta-quotes,
and one containing the (derived) types of the functions: for example:
f :: Num a => a -> a
f a = a + 1
g b = putStrLn (show b)
We would get one structure containing the definitions of f & g and the
type sig for f, and another containing the (derived) type-sig for g.
The programmer could then merge the two structures if wanted.
>
>
>And, of course, it's work do to.
>
>The big one is (b). A pragmatist would say just go ahead and hack
>something up -- if you get type information it'll be accurate, but
>there's no guarantee of what you'll get. But I hate that.
>
>
Even if more information is supplied outside the meta-quote context,
any more general type derived inside is not wrong... it might just
be more generalised than necessasry - but it is still a correct type,
and I have no problem with is being more general than necesary - it
makes sense that the code inside the meta-quotes should be viewed
as a constant fragment, so its type should be fixed irrespective of the
context in which it is used...
>So that's why I keep postponing it. Better ideas welcomed.
>
>
This is really very useful, for example we can use it to let the compiler
derive the constraints on a function (using class methods), and then
extract the constraints from the type and build an instance... This should
make it possible to derive a class instance from a function:
$(derive ''Show [| showsPrec _ (MyType a) = shows a |] )
which could generate:
instance Show a => Show (MyType a) where
showsPrec _ (MyType a) = shows a
Keean.
More information about the template-haskell
mailing list