
#11343: Unable to infer type when using DuplicateRecordFields -------------------------------------+------------------------------------- Reporter: mpickering | Owner: adamgundry Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler (Type | Version: 7.11 checker) | Resolution: | Keywords: ORF 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 adamgundry): When I said "known type" I meant the type of the variable * given by a signature (or determined by bidirectional type inference) at the binding site, if it is in the same group of mutually-recursive declarations; or * determined after type-checking, if it is in a previous group of declarations. Under this approach, the following would work: {{{#!hs f (x :: A) = x { a = 5 } g :: A -> A g x = x { a = 5 } h = aThing { a = 5 } }}} whereas these would not: {{{#!hs k x = (x :: A, x { a = 5 }) l (x :: Bool -> A) = (x True) { a = 5 } }}} This is a similar distinction to that made in bidirectional type inference for higher-rank types, where variables can be given a polymorphic type scheme by a signature or a pushed-in scheme, but inferred types must be monomorphic. I think it's easy to implement (and I've done so): given an update of a variable, look up the Id and check if its (un-zonked) type is a TyCon. One downside is that it invalidates certain syntactic transformations, such as inlining or lambda-lifting. But so do lots of other things! I've also experimented with an alternative approach: use the inferred type of the expression being updated. This is extremely easy to implement, as it simply requires deleting one guard. Moreover, it covers all the above cases and lots more. However, it doesn't have a nice declarative specification; it is rather dependent on the typechecker implementation. For example, {{{#!hs k x = (x :: A, x { a = 5 }) }}} is accepted but {{{#!hs k' x = (x { a = 5 }, x :: A) }}} is not. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11343#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler