Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#5616 closed bug (invalid)

TH type quotes cannot contain free type variables

Reported by: Lennart Owned by:
Priority: normal Milestone:
Component: Template Haskell Version: 7.2.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


A type quote cannot contain a free type variable, e.g.

module TH where
import Language.Haskell.TH

foo = [t| a |]

This is very awkward when passing arguments that are going into instance declarations since these need to have free type variables.

Change History (4)

comment:1 Changed 5 years ago by simonpj

Resolution: invalid
Status: newclosed

Template Haskell is lexically scoped! That's supposed to be one of its main features! You can't have an unbound term variable either.

You can get dynamic binding using mkName, but not with the quotation syntax, by design.


comment:2 Changed 5 years ago by augustss

So where should a be bound in this example?

inst t1 t2 = [d| instance C $t1 $t2 |]

$(inst [t| [a] |] [t| a |])

comment:3 Changed 5 years ago by simonpj

I asked in email: Can’t you pass the whole type?

inst t = [d| instance $t |]

You replied. No, you can’t. Both of those give you the error Malformed instance header.

Indeed! How could we possibly type check the declaration in

inst t = [d| instance $t where
               op x = x+2

All the usual stuff for type checking instance declarations assumes that we know the class, and indeed the instantiating types, of an instance declaration. Else how would we know whether ‘op came from the right class, or op x = x+2` has the right type.

I think the real answer here is in my blog post about Template Haskell. We can’t reasonably typecheck such declarations, but it is very convenient to use the quotation syntax. So support the quotation syntax, but don’t typecheck it. Restrict typechecking of Template Haskell to expressions, and do the Full Job a la MetaMl. See my blog post.

Here’s another example, even more extreme:

        foo :: Name -> Q [Dec]
	foo t = [d|  $t = MkT Int |]

Here I want to splice in the name of the type to be declared. Reasonable enough, and you can do it if you use explicit constructors, but totally impossible using quotation syntax.

Do you like the blog post ideas? How much does it matter to you?


comment:4 Changed 5 years ago by augustss

I like your proposal in the blog post. That said, it doesn't matter to me at all really. I hardly ever use TH, and the one time I used it I pretty quickly came to the conclusion that quotations where pretty much useless for my purposes, so I switched to using Exp.

Note: See TracTickets for help on using tickets.