[GHC] #9443: Regression from 7.6.3 to 7.8.3: could not coerce because argument "has role Nominal"

#9443: Regression from 7.6.3 to 7.8.3: could not coerce because argument "has role Nominal" -------------------------------------+------------------------------------- Reporter: bernalex | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Keywords: | Operating System: Architecture: x86_64 (amd64) | Unknown/Multiple Difficulty: Unknown | Type of failure: GHC Blocked By: | rejects valid program Related Tickets: | Test Case: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- This file works fine with 7.6.3: https://github.com/plaimi/plailude/blob/master/src/Data/Time/Units.hs But with 7.8.3, every newtype has an error message like: {{{ Could not coerce from ‘TimeUnit Integer’ to ‘TimeUnit (Year a)’ || because the first type argument of ‘TimeUnit’ has role Nominal, || but the arguments ‘Integer’ and ‘Year a’ differ || arising from the coercion of the method ‘timeVal’ from type || ‘forall n. (TimeUnit Integer, Num n) => Integer -> n’ to type || ‘forall n. (TimeUnit (Year a), Num n) => Year a -> n’ }}} To make the code work again, I need to remove a redundant type constraint from: {{{#!hs class TimeUnit t where timeVal :: (TimeUnit t, Num n) => t -> n }}} Turning it into: {{{#!hs class TimeUnit t where timeVal :: Num n => t -> n }}} The constraint is redundant because it is already implied by 'class TimeUnit t'. I suspect this is a regression. I would be happy to work on it, but I don't have time right now, so I'm putting it here for visibility, feedback, and to remember it in the first place. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9443 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9443: Regression from 7.6.3 to 7.8.3: could not coerce because argument "has role Nominal" -------------------------------------+------------------------------------- Reporter: bernalex | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: Operating System: | Architecture: x86_64 (amd64) Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Changes (by slyfox): * cc: slyfox (added) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9443#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9443: Regression from 7.6.3 to 7.8.3: could not coerce because argument "has role Nominal" -------------------------------------+------------------------------------- Reporter: bernalex | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: Operating System: | Architecture: x86_64 (amd64) Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Changes (by bernalex): * cc: slyfox (removed) * cc: eir@…, slyich@…, haskell@… (added) Comment: Nilkas and Trofi helped me out a bit. It seems this is due to the new role-inference mechanism. As such, it's perhaps not a regression per se. I do think GHC should accept this as a valid program though. CC'ing Richard, as Trofi mentioned that he was the GND/roles guy. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9443#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9443: Regression from 7.6.3 to 7.8.3: could not coerce because argument "has role Nominal" -------------------------------------+------------------------------------- Reporter: bernalex | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: Operating System: | Architecture: x86_64 (amd64) Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Description changed by bernalex: Old description:
This file works fine with 7.6.3: https://github.com/plaimi/plailude/blob/master/src/Data/Time/Units.hs
But with 7.8.3, every newtype has an error message like: {{{ Could not coerce from ‘TimeUnit Integer’ to ‘TimeUnit (Year a)’ || because the first type argument of ‘TimeUnit’ has role Nominal, || but the arguments ‘Integer’ and ‘Year a’ differ || arising from the coercion of the method ‘timeVal’ from type || ‘forall n. (TimeUnit Integer, Num n) => Integer -> n’ to type || ‘forall n. (TimeUnit (Year a), Num n) => Year a -> n’ }}}
To make the code work again, I need to remove a redundant type constraint from: {{{#!hs class TimeUnit t where timeVal :: (TimeUnit t, Num n) => t -> n }}}
Turning it into: {{{#!hs class TimeUnit t where timeVal :: Num n => t -> n }}}
The constraint is redundant because it is already implied by 'class TimeUnit t'.
I suspect this is a regression. I would be happy to work on it, but I don't have time right now, so I'm putting it here for visibility, feedback, and to remember it in the first place.
New description: This file works fine with 7.6.3: https://github.com/plaimi/plailude/blob/25d2a811a5d1b9b48ae8534bca10cc379830... But with 7.8.3, every newtype has an error message like: {{{ Could not coerce from ‘TimeUnit Integer’ to ‘TimeUnit (Year a)’ || because the first type argument of ‘TimeUnit’ has role Nominal, || but the arguments ‘Integer’ and ‘Year a’ differ || arising from the coercion of the method ‘timeVal’ from type || ‘forall n. (TimeUnit Integer, Num n) => Integer -> n’ to type || ‘forall n. (TimeUnit (Year a), Num n) => Year a -> n’ }}} To make the code work again, I need to remove a redundant type constraint from: {{{#!hs class TimeUnit t where timeVal :: (TimeUnit t, Num n) => t -> n }}} Turning it into: {{{#!hs class TimeUnit t where timeVal :: Num n => t -> n }}} The constraint is redundant because it is already implied by 'class TimeUnit t'. I suspect this is a regression. I would be happy to work on it, but I don't have time right now, so I'm putting it here for visibility, feedback, and to remember it in the first place. -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9443#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9443: Regression from 7.6.3 to 7.8.3: could not coerce because argument "has role Nominal" -------------------------------------+------------------------------------- Reporter: bernalex | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: Operating System: | Architecture: x86_64 (amd64) Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by goldfire): I don't think this is a bug, but I suppose I could be convinced otherwise. Consider this: {{{#!hs class C a where meth :: D a => a -> a }}} Note that the constraint on `meth` is ''not'' `C a`, but some other class `D a`. If we wish to derive an instance of `C` via GND, the derived instance will use the exact same implementation of `meth` as does the original instance. BUT, the newtype (say, `Year a`) may have a ''different'' instance for `D` compared to the representation type (`Integer`). So, reusing the old implementation would be bogus. That's why class parameters default to have nominal roles. Of course, if we knew that the `D` instances were in fact the same, then the derivation makes good sense. But GHC doesn't track "instance equality" (which could just mean that one instance is the GND of the other). In the case presented here, the instance equality is guaranteed, as we're performing the GND to make the instances equal. However, detecting this, in general, is hard, and this seems like enough of a corner case to let it go unfixed. Does that explain it? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9443#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9443: Regression from 7.6.3 to 7.8.3: could not coerce because argument "has role Nominal" -------------------------------------+------------------------------------- Reporter: bernalex | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: Operating System: | Architecture: x86_64 (amd64) Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by haasn): I agree that the class definition you gave should not be allowed. The bug as presented here is a very special case, namely the case where we have: {{{ class C a where meth :: C a => a -> a }}} This constraint is redundant because the context already implies it. So a fix for this issue would ''not'' necessarily imply allowing instance coercions in general - it would only allow instance coercions in the context of an instance coercion for that same instance, which is a rather minor detail. If this can be fixed easily, that's good; but if it can't, I don't think there's much of a loss. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9443#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9443: Regression from 7.6.3 to 7.8.3: could not coerce because argument "has role Nominal" -------------------------------------+------------------------------------- Reporter: bernalex | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: Operating System: | Architecture: x86_64 (amd64) Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by bernalex): I fully agree with Niklas. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9443#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9443: Regression from 7.6.3 to 7.8.3: could not coerce because argument "has role Nominal" -------------------------------------+------------------------------------- Reporter: bernalex | Owner: Type: bug | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: wontfix | Keywords: Operating System: | Architecture: x86_64 (amd64) Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Changes (by goldfire): * status: new => closed * resolution: => wontfix Comment: The way to handle the original case is to detect the redundant constraint and eliminate it, before doing any other processing. However, GHC does not do this currently, and the choice would have runtime consequences I think -- it would speed programs up, which now have fewer dictionaries to pass. I'm not inclined to make this change: perhaps the user has good reasons for the redundancy. Short of that, I don't see a way to fix this without contortions. Given the comments above, I'm closing as wontfix. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9443#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC