[Haskell-cafe] Template Haskell, information about data constructor types

Simon Peyton-Jones simonpj at microsoft.com
Thu Jun 21 18:03:55 EDT 2007


Sorry to be slow. Instead of

| Language.Haskell.TH> $( reify (mkName "Maybe") >>= error . show )

say

| Language.Haskell.TH> $( reify ''Maybe >>= error . show )

Which works fine.  The notation ''Maybe means "the type constructor Maybe that's in scope".

When you use mkName, TH builds a Language.Haskell.TH.Name which just contains the string "Maybe", and reify interprets that as a data constructor.  This is really a design flaw.  Perhaps a Name should contain a name-space.  That would be useful here (the NameSpace would say "I'm a tycoon").  But it's *not* useful when (say) lambda-binding a local variable.  Or maybe reify should take a NameSpace argument.

Anyway that's the problem and a solution is to hand.  But if you have a good idea for a better design, please yell.  And do please update the Wiki with whatever you have learned!

Simon


| -----Original Message-----
| From: haskell-cafe-bounces at haskell.org [mailto:haskell-cafe-
| bounces at haskell.org] On Behalf Of Neil Mitchell
| Sent: 04 June 2007 10:46
| To: Simon Peyton-Jones
| Cc: Haskell Café
| Subject: Re: [Haskell-cafe] Template Haskell, information about data
| constructor types
|
| Hi Simon,
|
| On 6/4/07, Simon Peyton-Jones <simonpj at microsoft.com> wrote:
| > | Where typeApp splits a type to find its constructor, ctorTypes gets
| > | the types of the fields, and dataCtors gets the constructors in a
| data
| > | type. Unfortunately reify doesn't seem to work on types. Is it
| > | possible to do what I am after?
| >
| > reify takes a Name, not a Type.
|
| I am passing it a name, since I pattern match on the ConT:
|
|        let (ConT c, cs) = typeApp t
|        TyConI dat <- reify c
|
| typeApp follows the AppT's to get a vector apply, so ConT is at the
| very left of a chain on AppT.
|
| >  Perhaps you mean that reify doesn't work on type constructors?
| (E.g. reify ''Maybe).
| > It should -- if you think it doesn't can you concoct a test case and
| submit it?
|
| I'm not sure if I'm doing something wrong, as I haven't managed to get
| it working for any type constructors. A test case:
|
| ghci -fth
| Prelude> :m Language.Haskell.TH
| Language.Haskell.TH> $( reify (mkName "Maybe") >>= error . show )
|
| Results in:
|
| <interactive>:1:3:
|     `Maybe' is not in scope at a reify
|     In the expression:
|         $[splice]((reify (mkName "Maybe")) >>= (error . show))
|     In the definition of `it':
|         it = $[splice]((reify (mkName "Maybe")) >>= (error . show))
|
| <interactive>:1:3:
|     Exception when trying to run compile-time code:
|       user error (IOEnv failure)
|       Code: let
|               >>= = (>>=) Q $dMonad
|               $dMonad = Language.Haskell.TH.Syntax.$f20
|               show = show Info $dShow
|               $dShow = Language.Haskell.TH.Syntax.$f60
|             in
|               (>>=) [Info, Exp]
|                 (reify (mkName "Maybe"))
|                 ((.) [[Char], Q Exp, Info] (error (Q Exp)) show)
|     In the expression:
|         $[splice]((reify (mkName "Maybe")) >>= (error . show))
|     In the definition of `it':
|         it = $[splice]((reify (mkName "Maybe")) >>= (error . show))
|
| The initial error is that Maybe is not in scope at reify. Changing to
| "Data.Maybe.Maybe" doesn't help, trying "String" doesn't work,
| creating a module and declaring a type in there then putting that
| fragment in the file doesn't work.
|
| Thanks
|
| Neil
| _______________________________________________
| Haskell-Cafe mailing list
| Haskell-Cafe at haskell.org
| http://www.haskell.org/mailman/listinfo/haskell-cafe


More information about the Haskell-Cafe mailing list