Jeremy Shaw | 7 Sep 2011 21:50
Gravatar

change in [d| |] and creating instances in template-haskell 2.7

Hello,

I have some code that likes like this, which works in template-haskell  
2.5 / GHC 7.0.3:

---------------
{-# Language TemplateHaskell, TypeFamilies #-}
module Show where

import Language.Haskell.TH

class Bar a where
   bar :: a -> String

inferBar :: Name -> Q [Dec]
inferBar typeName =
   do s <- [d| bar _ = "sucker"
             |]
      d <- instanceD (return []) (appT (conT ''Bar) (conT typeName))  
(map return s)
      return [d]

-----------------

$(inferBar ''Bool)

But, in template-haskell 2.6 / GHC 7.2.1, I get an error,

    Warning: No explicit method nor default method for `bar'
     In the instance declaration for `Bar Bool'
(Continue reading)

Simon Peyton-Jones | 8 Sep 2011 11:00
Picon
Favicon
Gravatar

RE: [Template-haskell] change in [d| |] and creating instances in template-haskell 2.7

[Redireting to ghc users; the TH list is pretty dormant and I keep thinking I should close it down altogether.]

Jeremy

Actually this is by design.  See the long thread at http://hackage.haskell.org/trac/ghc/ticket/5375

When you say

| inferBar typeName =
|    do s <- [d| bar _ = "sucker"
|              |]

you are asking for a *new* definition bar _ = "sucker".  But in an instance declaration you have to mention the
*existing* method name.  

To put it another way, do you expect this to work?

  do { bar_nm <- newName "bar"
     ; return (InstanceD [] <type> [FunD bar_nm <rhs>]) }

where you make up a *fresh name* (whose string-name is "bar") and use it in an instance declaration binding.

I suppose you could argue that for the odd case of instance decls, TH should ignore the exact identity of the
method name, and just use its string name. It would be convenient; but another weirdness too.

User advice welcome!

Simon

| -----Original Message-----
(Continue reading)

Jeremy Shaw | 8 Sep 2011 17:42
Gravatar

Re: [Template-haskell] change in [d| |] and creating instances in template-haskell 2.7


On Sep 8, 2011, at 4:00 AM, Simon Peyton-Jones wrote:

> [Redireting to ghc users; the TH list is pretty dormant and I keep  
> thinking I should close it down altogether.]
>
> Jeremy
>
> Actually this is by design.  See the long thread at http://hackage.haskell.org/trac/ghc/ticket/5375
>
> When you say
>
> | inferBar typeName =
> |    do s <- [d| bar _ = "sucker"
> |              |]
>
> you are asking for a *new* definition bar _ = "sucker".  But in an  
> instance declaration you have to mention the *existing* method name.

Right. That makes sense.

> To put it another way, do you expect this to work?
>
>  do { bar_nm <- newName "bar"
>     ; return (InstanceD [] <type> [FunD bar_nm <rhs>]) }
>
> where you make up a *fresh name* (whose string-name is "bar") and  
> use it in an instance declaration binding.

no.
(Continue reading)

Simon Peyton-Jones | 8 Sep 2011 19:07
Picon
Favicon
Gravatar

RE: [Template-haskell] change in [d| |] and creating instances in template-haskell 2.7

| Yeah. I would expect this to work:
| 
| inferBar2 :: Name -> Q [Dec]
| inferBar2 typeName =
|    [d| instance Bar $(conT typeName) where
|          bar _ = "sucker"
|      |]
| 
| But I get the same error:
| 
|      inferBar2 'Bool
|    ======>
|      show-test.hs:4:3-18
|      instance Bar Bool where
|          { bar_aTK _ = "sucker" }

Yes that should work. And it does with HEAD.  I fixed a bunch of stuff in the ticket I cited.  Maybe try a snapshot distribution?

Simon
Jeremy Shaw | 8 Sep 2011 19:39
Gravatar

Re: [Template-haskell] change in [d| |] and creating instances in template-haskell 2.7

Ah cool.

I just patched the code so that it uses mkName explicitly for now  
since it is Happstack related code and I want it to work the most  
places possible.

Thanks!
- jeremy

On Sep 8, 2011, at 12:07 PM, Simon Peyton-Jones wrote:

> | Yeah. I would expect this to work:
> |
> | inferBar2 :: Name -> Q [Dec]
> | inferBar2 typeName =
> |    [d| instance Bar $(conT typeName) where
> |          bar _ = "sucker"
> |      |]
> |
> | But I get the same error:
> |
> |      inferBar2 'Bool
> |    ======>
> |      show-test.hs:4:3-18
> |      instance Bar Bool where
> |          { bar_aTK _ = "sucker" }
>
> Yes that should work. And it does with HEAD.  I fixed a bunch of  
> stuff in the ticket I cited.  Maybe try a snapshot distribution?
>
(Continue reading)


Gmane