Type-changing record update catch-all in sum type doesn't typecheck
Apologies for the confusing title/summary, but that is about as succinct as I could be.
Rather than try to describe this in english, here is the smallest example I could repro with.
I want to write this:
import Data.Char
data R a
= Foo { x :: a, y :: a }
| Bar { x :: a }
| Baz { x :: a }
ordify :: R Char -> R Int
ordify r@(Foo {}) = r { x = ord (x r), y = ord (y r) }
ordify r = r { x = ord (x r) }
But that fails to typecheck:
$ ghci Test.hs
GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( Test.hs, interpreted )
Test.hs:10:21:
Couldn't match type ‘Char’ with ‘Int’
Expected type: R Int
Actual type: R Char
In the expression: r
In the expression: r {x = ord (x r)}
Failed, modules loaded: none.
Instead, I have to resort to enumerating all the remaining constructors:
import Data.Char
data R a
= Foo { x :: a, y :: a }
| Bar { x :: a }
| Baz { x :: a }
ordify :: R Char -> R Int
ordify r@(Foo {}) = r { x = ord (x r), y = ord (y r) }
ordify (Bar x) = Bar (ord x)
ordify (Baz x) = Baz (ord x)
The sum type has the property that every constructor has the field x, and some constructors have fields which are also parameterized over x's type 'a'. I would expect my first example, with the catch-all record-update to typecheck, but it doesn't. I suspect GHC thinks the catch-all case of ordify might be passed a Foo constructor, in which case the record update would be ill-typed, even though that is impossible due to the first case matching Foo explicitly.
Trac metadata
Trac field | Value |
---|---|
Version | 7.10.2 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler (Type checker) |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |