
#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