[GHC] #12240: Common Sense for Type Classes

GHC ghc-devs at haskell.org
Thu Jul 14 03:04:19 UTC 2016


#12240: Common Sense for Type Classes
-------------------------------------+-------------------------------------
        Reporter:  Mathnerd314       |                Owner:
            Type:  feature request   |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.0.1
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  GHC rejects       |  Unknown/Multiple
  valid program                      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by Mathnerd314):

 > What should the inferred type of g be?

 My preferred answer is (1). The reasoning is something like:
 * an untyped function binding... infer a type signature
 * f creates a constraint, so it's `g :: forall b. C Int b => Int -> b`
 * it typechecks - done

 This is distinct from `x = fst f` in the original example. There, `x` is a
 pattern binding and the monomorphism restriction applies. `x` cannot have
 a constraint in the inferred type, thus GHC is forced to choose an
 instance, in particular the `C Int Char` instance, and so the inferred
 type is `x :: Char`.

 Similarly, `show (g 2)` generates constraints `Show b, C a b, Num a`,
 which can either go into the given constraints or be solved, depending on
 the context.

 > What your proposal seems to suggest is an alternate way to do
 defaulting, by consulting the instance environment in question.

 Defaulting happens in `simpl_top`, while instance resolution happens in
 `solveSimpleWanteds` in `simpl_loop`. There's a note explaining that
 defaulting used to be in `simpl_loop`, but doing it outside any
 implications fixed some programs. I wonder if, analogously, moving
 instance resolution out near defaulting would result in a similar
 improvement. It does seem clear that defaulting and top-level instance
 resolution are intimately entwined with the instance environment.

 > Specifically, if I have an ambiguous type variable v which occurs in
 some class C t1 v ..., if there is only ONE choice of v which allows the
 instance resolution to go through, I should default v to that one!

 That doesn't sound quite right. For example:
 {{{#!hs
 class X a b c
 instance X [a] (Maybe a) Bool
 instance X [a] [a] Char

 x = (\(d :: Dict (X [a] (Maybe Int) b)) -> typeOf d) Dict
 -- wanted: x = "Dict (X [Int] (Maybe Int) Bool)"
 }}}

 I don't see how defaulting would turn `[a]` into `[Int]`, if it did
 something variable-by-variable.
 (Also note that defaulting as currently implemented only applies to one-
 parameter type classes)

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


More information about the ghc-tickets mailing list