Ticket #7066 (new bug)

Opened 10 months ago

Last modified 7 months ago

isInstance does not work for compound types

Reported by: edsko Owned by: simonpj
Priority: normal Milestone: 7.8.1
Component: Template Haskell Version: 7.4.2
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description

Consider

import Language.Haskell.TH.Syntax                                                
                                                                                 
data A = A                                                                       
                                                                                 
test :: Q [Dec]                                                                  
test = do                                                                        
  tp <- [t| (Int, A) |]                                                          
  inst1 <- isInstance ''Show [ tp ]                                              
  runIO $ print inst1                                                            
  return []  

This prints True even though there is no Show instance for A (the Show instance it finds is for pairs, but it does not verify that there are Show instances for the pair components).

Change History

Changed 10 months ago by simonpj

  • owner set to simonpj
  • difficulty set to Unknown

That's true, and currently so by design. What if you did want to ask "is there an instance for pairs?" You could try making up fresh type variables 'x' and 'y', say, but then with the behaviour you were expecting it would try to find an instance for (Show x), fail, and hence return an empty list.

It should be better documented, I agree, but I'm not sure what alternative behaviour would make sense.

I need review and commit Reiner's patches from #5469, but then I'll add the docs.

Changed 10 months ago by edsko

I see. Fair enough, but then it would be very useful if a separate function was provided that does have the "expected" behaviour for things like (Int, A) (for some definition of "expected" :). It's not obvious to me that such a function is easily user-definable.

Changed 10 months ago by simonpj

Would you care to define the "expected" behaviour that you expect?

Changed 10 months ago by edsko

Oh, I'm sorry. I would expect

isInstance clss typs

to return True if and only if I can safely generate code (in my Template Haskell code) that relies on 'typs' being an instance of 'clss'. In the example above, I can not safely generate code that relies on a Show instance for (Int, A) because there is no Show instance for A. However, I can safely generate code that relies on a Show instance for (Int, Bool), say.

Context: In Cloud Haskell when you call 'remotable' on a monomorphic function f :: T1 -> T2, I automatically generate a top-level definition

f__sdict :: Static (SerializableDict T1)

but if T1 is not in fact serializable then this will subsequently cause a type error. So I would like to check (using isInstance) if T1 is an instance of Serializable before generating this code.

Changed 10 months ago by simonpj

What if the type contains type variables?

Changed 10 months ago by edsko

Yes, I guess that's the tricky case -- but this problem already exists. isInstance just checks if reifyInstances doesn't return the empty list; so reifyInstances for Show (a, Int) could return

Instance (Show a) => Instance (a, Int)

just like it returns

Instance (Show a, Show b) => Instance (a, b)

now for that exact same argument. If 'isInstance' is not modified, then an answer of True would mean: this could be satisfied (if there are instances for the type variables), and for monomorphic types it would mean yes, this is satisfied.

Changed 7 months ago by igloo

  • milestone set to 7.8.1
Note: See TracTickets for help on using tickets.