#7437: peculiar behaviour with default instances and type variables
---------------------------------+------------------------------------------
    Reporter:  bos               |       Owner:                             
        Type:  bug               |      Status:  new                        
    Priority:  normal            |   Milestone:                             
   Component:  Compiler          |     Version:  7.6.1                      
    Keywords:                    |          Os:  Unknown/Multiple           
Architecture:  Unknown/Multiple  |     Failure:  GHC accepts invalid program
  Difficulty:  Unknown           |    Testcase:                             
   Blockedby:                    |    Blocking:                             
     Related:                    |  
---------------------------------+------------------------------------------
Changes (by simonpj):

  * difficulty:  => Unknown


Comment:

 Here is what is going on.  When you replace the second sig for `default
 put` with the first, the type of the generic default method becomes
 {{{
   $gdmput :: forall a. Put a => forall t. (Generic t, GPut (Rep t)) => t
 -> [()]
 }}}
 and this is indeed ambiguous.  But the error message is unhelpful
 {{{
 T7437.hs:11:1:
     Ambiguous constraint `Put a'
       At least one of the forall'd type variables mentioned by the
 constraint
       must be reachable from the type after the '=>'
     When checking the class method: put :: a -> [()]
     In the class declaration for `Put'
 }}}
 Second, as things stand when you add `FlexibleInstances` that suppresses
 the ambiguity check (see `Note [The ambiguity check for type signatures]`
 in `TcMType.lhs`).  So instetad you get ambiguity where the generic defaul
 method is called.  The `instance Put Foo` really means
 {{{
 instance Put Foo where
   put = $gdmput
 }}}
 and so you get
 {{{
 T7437.hs:27:10:
     No instance for (Put a0) arising from a use of `T7437.$gdmput'
     The type variable `a0' is ambiguous
     Possible fix: add a type signature that fixes these type variable(s)
     Note: there is a potential instance available:
       instance Put Foo -- Defined at T7437.hs:27:10
     In the expression: (T7437.$gdmput)
     In an equation for `put': put = (T7437.$gdmput)
     In the instance declaration for `Put Foo'
 }}}
 Things for me (or someone) to think about
  * Improve the context info for the first message, which should at least
 give the ambiguous type.
  * Improve the ambiguity check, which is very crude at the moment.  The
 ambiguity check that is used for ''infered'' types is this. Given `f = e`
 in you infer the type `f :: type`, then would this type check?
 {{{
   g :: type
   g = f
 }}}#
   The ambiguity check for ''declared'' type should be the same, and it
 isn't.

 So this does not look urgent but clear rooom for improvement. Thanks for
 reporting.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7437#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler

_______________________________________________
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to