[GHC] #9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas ------------------------------------+------------------------------------- Reporter: simonpj | Owner: Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Keywords: | Operating System: Unknown/Multiple Architecture: Unknown/Multiple | Type of failure: None/Unknown Difficulty: Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | ------------------------------------+------------------------------------- The language extensions `-XIncoherentInstances` and `-XOverlappingInstances` (described in [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class- extensions.html#instance-overlap the user manual]) apply to every instance declaration in the module. Internally, however, GHC records this information on a per-instance-declaration basis. It would be much better for the programmer to be able to control these matters on a per-instance-declaration basis. Thus: {{{ instance Show a => Show [a] where {-# OVERLAPPABLE #-} ... instance Show [Char] where ... }}} We came across the need for this when discussing the `Typeable` instances. We have a generic instance like this: {{{ instance (Typeable f, Typeable a) => Typeable (f a) where .... }}} but also want {{{ instance KnownNat n => Typeable (n :: Nat) where ... }}} If we seek `(Typeable (x::Nat))`, we should pick the second instance even though in principle you might imagine that `x` might be instantiated to `(f a)`, for some `f` and `a`. But we know that there are no type constructors `f` of kind `blah -> Nat`, so this can never happen and it's safe to pick the second instance. So a local `{-# INCOHERENT #-}` pragma for this particular instance declaration would be very useful to express this fact. {{{ instance KnownNat n => Typeable (n :: Nat) where {-# INCOHERENT #-} ... }}} Quite apart from this special case, it's plain better to have per-instance control * Rather than a remote per-module flag, the pragma draws attention that ''this particular instance'' is incoherent, overlappable or whatever. * The current situation almost certainly means that more instances are marked overlapping than are really necessary. I have some design questions. * Where should the pragma appear, syntactically? {{{ instance {-# OVERLAPPABLE #-} Show a => Show [a] where ... or instance Show a => Show [a] {-# OVERLAPPABLE #-} where ... or instance Show a => Show [a] where {-# OVERLAPPABLE #-} }}} Remember that `SPECIALISE INSTANCE` pragmas appear in the third of the above positions, so I mildly favour that. * The user manual (link above) allows overlap if ''either'' instance is compiled with `-XOverlappingInstances` (see the rules towards the end of [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class- extensions.html#instance-overlap 7.6.3.5). It would be more explicit to have two pragmas, one to say "I can be overlapped" and one to say "I can overlap something else". The rule would then be that "either IX is marked `{-# OVERLAPPABLE #-}` or IY is marked `{-# OVERLAPPING #-}`. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------ Reporter: simonpj | Owner: diatchki Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Changes (by simonpj): * owner: => diatchki Comment: Iavor has agreed to execute on this. Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------ Reporter: simonpj | Owner: diatchki Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Description changed by simonpj: Old description:
The language extensions `-XIncoherentInstances` and `-XOverlappingInstances` (described in [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class- extensions.html#instance-overlap the user manual]) apply to every instance declaration in the module. Internally, however, GHC records this information on a per-instance-declaration basis.
It would be much better for the programmer to be able to control these matters on a per-instance-declaration basis. Thus: {{{ instance Show a => Show [a] where {-# OVERLAPPABLE #-} ...
instance Show [Char] where ... }}} We came across the need for this when discussing the `Typeable` instances. We have a generic instance like this: {{{ instance (Typeable f, Typeable a) => Typeable (f a) where .... }}} but also want {{{ instance KnownNat n => Typeable (n :: Nat) where ... }}} If we seek `(Typeable (x::Nat))`, we should pick the second instance even though in principle you might imagine that `x` might be instantiated to `(f a)`, for some `f` and `a`. But we know that there are no type constructors `f` of kind `blah -> Nat`, so this can never happen and it's safe to pick the second instance. So a local `{-# INCOHERENT #-}` pragma for this particular instance declaration would be very useful to express this fact. {{{ instance KnownNat n => Typeable (n :: Nat) where {-# INCOHERENT #-} ... }}} Quite apart from this special case, it's plain better to have per- instance control * Rather than a remote per-module flag, the pragma draws attention that ''this particular instance'' is incoherent, overlappable or whatever. * The current situation almost certainly means that more instances are marked overlapping than are really necessary.
I have some design questions. * Where should the pragma appear, syntactically? {{{ instance {-# OVERLAPPABLE #-} Show a => Show [a] where ... or instance Show a => Show [a] {-# OVERLAPPABLE #-} where ... or instance Show a => Show [a] where {-# OVERLAPPABLE #-} }}} Remember that `SPECIALISE INSTANCE` pragmas appear in the third of the above positions, so I mildly favour that.
* The user manual (link above) allows overlap if ''either'' instance is compiled with `-XOverlappingInstances` (see the rules towards the end of [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class- extensions.html#instance-overlap 7.6.3.5). It would be more explicit to have two pragmas, one to say "I can be overlapped" and one to say "I can overlap something else". The rule would then be that "either IX is marked `{-# OVERLAPPABLE #-}` or IY is marked `{-# OVERLAPPING #-}`.
New description: The language extensions `-XIncoherentInstances` and `-XOverlappingInstances` (described in [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class- extensions.html#instance-overlap the user manual]) apply to every instance declaration in the module. Internally, however, GHC records this information on a per-instance-declaration basis. It would be much better for the programmer to be able to control these matters on a per-instance-declaration basis. Thus: {{{ instance Show a => Show [a] where {-# OVERLAPPABLE #-} ... instance Show [Char] where ... }}} We came across the need for this when discussing the `Typeable` instances. We have a generic instance like this: {{{ instance (Typeable f, Typeable a) => Typeable (f a) where .... }}} but also want {{{ instance KnownNat n => Typeable (n :: Nat) where ... }}} If we seek `(Typeable (x::Nat))`, we should pick the second instance even though in principle you might imagine that `x` might be instantiated to `(f a)`, for some `f` and `a`. But we know that there are no type constructors `f` of kind `blah -> Nat`, so this can never happen and it's safe to pick the second instance. So a local `{-# INCOHERENT #-}` pragma for this particular instance declaration would be very useful to express this fact. {{{ instance KnownNat n => Typeable (n :: Nat) where {-# INCOHERENT #-} ... }}} Quite apart from this special case, it's plain better to have per-instance control * Rather than a remote per-module flag, the pragma draws attention that ''this particular instance'' is incoherent, overlappable or whatever. * The current situation almost certainly means that more instances are marked overlapping than are really necessary. I have some design questions. * Where should the pragma appear, syntactically? {{{ instance {-# OVERLAPPABLE #-} Show a => Show [a] where ... or instance Show a => Show [a] {-# OVERLAPPABLE #-} where ... or instance Show a => Show [a] where {-# OVERLAPPABLE #-} }}} Remember that `SPECIALISE INSTANCE` pragmas appear in the third of the above positions, so I mildly favour that. * The user manual (link above) allows overlap if ''either'' instance is compiled with `-XOverlappingInstances` (see the rules towards the end of [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class- extensions.html#instance-overlap 7.6.3.5]. It would be more explicit to have two pragmas, one to say "I can be overlapped" and one to say "I can overlap something else". The rule would then be that "either IX is marked `{-# OVERLAPPABLE #-}` or IY is marked `{-# OVERLAPPING #-}`. -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------ Reporter: simonpj | Owner: diatchki Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Description changed by simonpj: Old description:
The language extensions `-XIncoherentInstances` and `-XOverlappingInstances` (described in [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class- extensions.html#instance-overlap the user manual]) apply to every instance declaration in the module. Internally, however, GHC records this information on a per-instance-declaration basis.
It would be much better for the programmer to be able to control these matters on a per-instance-declaration basis. Thus: {{{ instance Show a => Show [a] where {-# OVERLAPPABLE #-} ...
instance Show [Char] where ... }}} We came across the need for this when discussing the `Typeable` instances. We have a generic instance like this: {{{ instance (Typeable f, Typeable a) => Typeable (f a) where .... }}} but also want {{{ instance KnownNat n => Typeable (n :: Nat) where ... }}} If we seek `(Typeable (x::Nat))`, we should pick the second instance even though in principle you might imagine that `x` might be instantiated to `(f a)`, for some `f` and `a`. But we know that there are no type constructors `f` of kind `blah -> Nat`, so this can never happen and it's safe to pick the second instance. So a local `{-# INCOHERENT #-}` pragma for this particular instance declaration would be very useful to express this fact. {{{ instance KnownNat n => Typeable (n :: Nat) where {-# INCOHERENT #-} ... }}} Quite apart from this special case, it's plain better to have per- instance control * Rather than a remote per-module flag, the pragma draws attention that ''this particular instance'' is incoherent, overlappable or whatever. * The current situation almost certainly means that more instances are marked overlapping than are really necessary.
I have some design questions. * Where should the pragma appear, syntactically? {{{ instance {-# OVERLAPPABLE #-} Show a => Show [a] where ... or instance Show a => Show [a] {-# OVERLAPPABLE #-} where ... or instance Show a => Show [a] where {-# OVERLAPPABLE #-} }}} Remember that `SPECIALISE INSTANCE` pragmas appear in the third of the above positions, so I mildly favour that.
* The user manual (link above) allows overlap if ''either'' instance is compiled with `-XOverlappingInstances` (see the rules towards the end of [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class- extensions.html#instance-overlap 7.6.3.5]. It would be more explicit to have two pragmas, one to say "I can be overlapped" and one to say "I can overlap something else". The rule would then be that "either IX is marked `{-# OVERLAPPABLE #-}` or IY is marked `{-# OVERLAPPING #-}`.
New description: The language extensions `-XIncoherentInstances` and `-XOverlappingInstances` (described in [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class- extensions.html#instance-overlap the user manual]) apply to every instance declaration in the module. Internally, however, GHC records this information on a per-instance-declaration basis. It would be much better for the programmer to be able to control these matters on a per-instance-declaration basis. Thus: {{{ instance Show a => Show [a] where {-# OVERLAPPABLE #-} ... instance Show [Char] where ... }}} We came across the need for this when discussing the `Typeable` instances. We have a generic instance like this: {{{ instance (Typeable f, Typeable a) => Typeable (f a) where .... }}} but also want {{{ instance KnownNat n => Typeable (n :: Nat) where ... }}} If we seek `(Typeable (x::Nat))`, we should pick the second instance even though in principle you might imagine that `x` might be instantiated to `(f a)`, for some `f` and `a`. But we know that there are no type constructors `f` of kind `blah -> Nat`, so this can never happen and it's safe to pick the second instance. So a local `{-# INCOHERENT #-}` pragma for this particular instance declaration would be very useful to express this fact. {{{ instance KnownNat n => Typeable (n :: Nat) where {-# INCOHERENT #-} ... }}} Quite apart from this special case, it's plain better to have per-instance control * Rather than a remote per-module flag, the pragma draws attention that ''this particular instance'' is incoherent, overlappable or whatever. * The current situation almost certainly means that more instances are marked overlapping than are really necessary. I have some design questions. * Where should the pragma appear, syntactically? {{{ instance {-# OVERLAPPABLE #-} Show a => Show [a] where ... or instance Show a => Show [a] {-# OVERLAPPABLE #-} where ... or instance Show a => Show [a] where {-# OVERLAPPABLE #-} }}} Remember that `SPECIALISE INSTANCE` pragmas appear in the third of the above positions, so I mildly favour that. * The user manual (link above) allows overlap if ''either'' instance is compiled with `-XOverlappingInstances` (see the rules towards the end of [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class- extensions.html#instance-overlap 7.6.3.5]). It would be more explicit to have two pragmas, one to say "I can be overlapped" and one to say "I can overlap something else". The rule would then be that "either IX is marked `{-# OVERLAPPABLE #-}` or IY is marked `{-# OVERLAPPING #-}`. -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas
-------------------------------------+------------------------------------
Reporter: simonpj | Owner: diatchki
Type: feature request | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.8.2
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture: Unknown/Multiple
Type of failure: None/Unknown | Difficulty: Unknown
Test Case: | Blocked By:
Blocking: | Related Tickets:
-------------------------------------+------------------------------------
Comment (by Iavor S. Diatchki

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas
-------------------------------------+------------------------------------
Reporter: simonpj | Owner: diatchki
Type: feature request | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.8.2
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture: Unknown/Multiple
Type of failure: None/Unknown | Difficulty: Unknown
Test Case: | Blocked By:
Blocking: | Related Tickets:
-------------------------------------+------------------------------------
Comment (by Iavor S. Diatchki

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------ Reporter: simonpj | Owner: diatchki Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by simonpj): What about the last bullet point of the ticket description? The relationship between two overlapping instances is not symmetrical. I suggested "OVERLAPPABLE" and "OVERLAPPING". Yes, it's a bit more fiddly, but much more explicit. Oh, and I suppose you should be able to have both. {{{ instance {-# OVERLAPPABE #-} C a where instance {-# OVERLAPPABLE, OVERLAPPING #-} C [a] where ... isntance {-# OVERLAPPING #-} C [Maybe a] where ... }}} Here the middle one overlaps `C a` and is overlapped by `C [Maybe a]`. Or is this over-elaborate? Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------ Reporter: simonpj | Owner: diatchki Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by simonpj): PS: could you also update the user manual? Are we going to deprecate `-XOverlappingInstances` in favour of these pragmas? (I vote yes.) In which case that's something else to do. Thanks Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------ Reporter: simonpj | Owner: diatchki Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by tibbe): There's been talk about implementing a `-XNoOrphanInstances` flag, which should make overlapping always safe (I think). If so perhaps it's useful to have a `-XOverlappingInstances` club to allow overlaps everywhere? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------ Reporter: simonpj | Owner: diatchki Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by simonpj): Safe or not, I still think it'd be better to signal it locally. Clubs are rather blunt instruments. Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------ Reporter: simonpj | Owner: diatchki Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by goldfire): The interaction between a hypothetical `-XNoOrphanInstances`, Safety, and overlapping instances is subtle -- the flags have to be put potentially on different modules to get the Safety requirement to work out. For this reason and in order to avoid blunt instruments, I favor also deprecating !OverlappingInstances. For the bulk of you surprised by this mysterious `-XNoOrphanInstances`, it's an idea that Edward Kmett, Gershom Bazerman, and I cooked up a few months ago. More information in due course! -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------ Reporter: simonpj | Owner: diatchki Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by diatchki): I like the OVERLAPPING and OVERLAPPABLE idea, and I was going to have a stab at implementing it. I just thought it'd be easier to start by simply exposing what GHC does first, before changing more things. So, this, and updating the manual is on my TODO list. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Operating System: Unknown/Multiple Differential Revisions: | Type of failure: None/Unknown Architecture: | Test Case: Unknown/Multiple | Blocking: Difficulty: Unknown | Blocked By: | Related Tickets: | -------------------------------------+------------------------------------- Comment (by diatchki): I thought some more about the OVERLAPPING and OVERLAPPABLE idea, but I couldn't come up with examples where I'd want to use that feature. So, for the time being, I'll leave the implementation as is, and document it accordingly. Related to this: having looked at the code for the instance database, I think it would be quite easy to implement "instance chains", which eliminates the need for overlapping instances in pretty much all situations that I've encountered them. I outlined the details in ticket #9334. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:12 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Operating System: Unknown/Multiple Differential Revisions: | Type of failure: None/Unknown Architecture: | Test Case: Unknown/Multiple | Blocking: Difficulty: Unknown | Blocked By: | Related Tickets: | -------------------------------------+------------------------------------- Comment (by simonpj): As I say on the other ticket, I think it'll be a hard sell to ''replace'' overlapping instances with instance chains. So I'd still really like to get the per-instance `{-# OVERLAPPING, OVERLAPPABLE #-}` pragmas proposed above. Would you still be willing to do that? Or, if not, would someone else? Thanks Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:13 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by diatchki): I know the code, so I don't mind doing it. Out of curiosity, do you have an example of when you may want to write just `OVERLAPPING` and not `OVERLAPABLE` or vice versa? The way I understand it, they have the following meanings: * `OVERLAPPING` says "I am a most general instance" (i.e., can overlap, but can't be overlapped), * `OVERLAPABLE` says "I am a most specific instance" (i.e., can't overlap, can be overlapped). So, they make some sense for the "edge-case" instances, but not for the ones inbetween, and I couldn't really think of good cases where I may want to put them on an instance. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:14 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by diatchki): As I started implementing this, it occurred to me that another interpretation of `OVERLAPPING` and `OVERLAPPABLE` is also possible: * `OVERLAPPING`: - may replace ''any'' more general instance; - may be replaced by more specific instances marked with `OVERLAPPING`. * `OVERLAPABLE`: - may be replaced by ''any'' more specific instance; - may replace more general instances marked with `OVERLAPABLE`. This interpretation has the advantage of specifying how to interact with "normal" instances (i.e., ones compiled in modules without special overlapping flags). The drawback is that there is no way for an instance to be sure that it won't be replaced. Perhaps that's OK though---I think the current system does not provide a way to do this anyway. See also #3877 for some related discussuion. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:15 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas
-------------------------------------+-------------------------------------
Reporter: simonpj | Owner: diatchki
Type: feature | Status: new
request | Milestone:
Priority: normal | Version: 7.8.2
Component: Compiler | Keywords:
Resolution: | Architecture: Unknown/Multiple
Operating System: | Difficulty: Unknown
Unknown/Multiple | Blocked By:
Type of failure: | Related Tickets:
None/Unknown |
Test Case: |
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
Comment (by Iavor S. Diatchki

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by jstolarek): I think this should also be mentioned in the release notes for 7.10. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:17 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonpj): Great stuff, thank you. I'll now deprecate `-XOverlappingInstances`. To finish this off I'd love someone to make INOCOHERET per-instance too! Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:18 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by diatchki): We can already mark individual instances as INCOHERENT. For example, in `Data.Typeable.Internal` we have an instance like this: {{{ instance {-# INCOHERENT #-} (Typeable f, Typeable a) => Typeable (f a) where ... }}} In the fourth bullet of the commit message (comment:16 above), I just meant that instances annotated with INCOHERENT work in the same way they did before. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:19 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonpj): Ah yes, thanks. As you say in comment:16, an instance can have just one of these four properties. But the rules in the user manual then don't seem quite right. They currently read thus (in my HEAD, somewhat improved from HEAD): {{{ The willingness to be overlapped or incoherent is a property of the instance declaration itself, controlled as follows: * An instance is overlappable if it has an OVERLAPPABLE or OVERLAPS pragama, or if the module in which the instance appears is compiled with -XOverlappingInstances. * An instance is overlapping if it has an OVERLAPPING or OVERLAPS pragama, or if the module in which the instance appears is compiled with -XOverlappingInstances. * An instance is incoherent if it has an INCOHERENT pragama, or if the module in which the instance appears is compiled with -XIncoherentInstances. Now suppose that, in some client module, we are searching for an instance of the target constraint (C ty1 .. tyn). The search works like this. * Find all instances I that match the target constraint; that is, the target constraint is a substitution instance of I. These instance declarations are the candidates. * Find all non-candidate instances that unify with the target constraint. Such non-candidates instances might match when the target constraint is further instantiated. If all of them are incoherent, proceed; if not, the search fails. * Eliminate any candidate IX for which both of the following hold: * There is another candidate IY that is strictly more specific; that is, IY is a substitution instance of IX but not vice versa. * Either IX is overlappable or IY is overlapping. * If only one candidate remains, pick it. Otherwise if all remaining candidates are incoherent, pick an arbitrary candidate. }}} As things stand, and in the implementation, INCOHERENT does not imply "overlappable" or "overlapping". And it probably should. After all, if you have two candidate instances {{{ (incoherent) C [a] (no pragma) C [Int] }}} you probably want to pick the latter not the former! The alternative (which I do not advocate) is to treat overlapping and incoherent as separate things, so you can say {{{ instance {-# INCOHERENT, OVERLAPPABLE #-} C [a] }}} So I suggest we change the spec above, and the impl to say {{{ * An instance is overlappable if it has an OVERLAPPABLE or OVERLAPS or INCOHERENT pragama, or if the module in which the instance appears is compiled with -XOverlappingInstances or -XIncoherentInstances. ...and similarly "overlapping" }}} Do you agree? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:20 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonpj): One more thing. Look at this note in `InstEnv`: {{{ Note [Incoherent instances] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ For some classes, the choice of a particular instance does not matter, any one is good. E.g. consider class D a b where { opD :: a -> b -> String } instance D Int b where ... instance D a Int where ... g (x::Int) = opD x x -- Wanted: D Int Int For such classes this should work (without having to add an "instance D Int Int", and using -XOverlappingInstances, which would then work). This is what -XIncoherentInstances is for: Telling GHC "I don't care which instance you use; if you can use one, use it." Should this logic only work when *all* candidates have the incoherent flag, or even when all but one have it? The right choice is the latter, which can be justified by comparing the behaviour with how -XIncoherentInstances worked when it was only about the unify-check (note [Overlapping instances]): Example: class C a b c where foo :: (a,b,c) instance C [a] b Int instance [incoherent] [Int] b c instance [incoherent] C a Int c Thanks to the incoherent flags, [Wanted] C [a] b Int works: Only instance one matches, the others just unify, but are marked incoherent. So I can write (foo :: ([a],b,Int)) :: ([Int], Int, Int). but if that works then I really want to be able to write foo :: ([Int], Int, Int) as well. Now all three instances from above match. None is more specific than another, so none is ruled out by the normal overlapping rules. One of them is not incoherent, but we still want this to compile. Hence the "all-but-one-logic". }}} That makes sense, but it doesn't implement the rule in the manual (comment:20). I think the last bullet should therefore read {{{ * If exactly one non-incoherent candidate remains, pick it. If all remaining candidates are incoherent, pick an arbitary one. Otherwise fail. }}} Do you agree? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:21 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonpj): Sigh. One last observation. Read the Description of this ticket. I thought we'd end up with {{{ instance {-# INCOHERENT #-} Typeable (n::Nat) where ... instance (Typeable f, Typeable a) => Typeable (f a) where ... }}} The weird one is the `Typeable (n:Nat)` instance. Our reasoning is that we don't want to worry about instantiations of `n`. And this is what we wrote in the Description. But actually the rules above mean that we have to write this {{{ instance Typeable (n::Nat) where ... instance {-# INCOHERENT #-} (Typeable f, Typeable a) => Typeable (f a) where ... }}} (and that is indeed what is in `Data.Typeable.Internals` today. The incoherent flag is on the innocent `Typeable (f a)` declaration. Obviously incoherence is an area where we don't expect "right" answers. But the above does suggest that it could make sense to change the behaviour of incoherence, to this: ignoring a non-candidate unifying instance when (and only when) there is an incoherent matching instance. Here is another example to illustrate {{{ class C a where op :: a -> Bool instance {-# INCOHERENT? #-} C [a] where op x = True instance {-# INCOHERENT? #-} C [Int] where op x = False f :: [a] -> Bool f x = op x }}} Without incoherence, `f` is rejected even with overlapping instances, because the choice depends on the instantiation of `a`. So, which instance needs `{-# INCOHERENT #-}` to make it acceptable? Today the answer is the second one; with the change proposed here, it'd be the first one. I don't feel very strongly about this, but the `Typeable` example (which drove the entire thread!) is quite compelling to me. Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:22 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by goldfire): I agree with Simon's comment:20 and comment:21. I think those changes are for the better. As to comment:22, it sounds like you wish to distinguish between `INCOHERENTABLE` and `INCOHERENTING`. (I don't want to use those names, just draw the parallel to the `OVERLAP` pragmas.) Is this a reasonable interpretation of what you're saying? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:23 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonpj): Replying to [comment:23 goldfire]:
As to comment:22, it sounds like you wish to distinguish between `INCOHERENTABLE` and `INCOHERENTING`. (I don't want to use those names, just draw the parallel to the `OVERLAP` pragmas.) Is this a reasonable interpretation of what you're saying?
Yes, but I ''really'' don't want to actually have that complexity. Obvious alternatives: * Current behaviour: INCOHERENT means INCOHERNTING * Behaviour proposed in comment:22: INCOHERENT means INCOHERENTABLE * Another alternative: INCOHERENT means both INCOHERENTING and INCOHERENTABLE -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:24 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonpj): Just for completeness, here is the proposed specification again, with the fixes above, except for the remarks about incoherence in comments 22-24: {{{ The willingness to be overlapped or incoherent is a property of the instance declaration itself, controlled as follows: * An instance is "incoherent" if it has an INCOHERENT pragama, or if it appears in a module compiled with -XIncoherentInstances. * An instance is "overlappable" if it has an OVERLAPPABLE or OVERLAPS pragama, or if it appears in a module compiled with -XOverlappingInstances, or if the instance is incoherent. * An instance is "overlapping" if it has an OVERLAPPING or OVERLAPS pragama, or if it appears in a module compiled with -XOverlappingInstances, or if the instance is incoherent. compiled with -XOverlappingInstances. Now suppose that, in some client module, we are searching for an instance of the target constraint (C ty1 .. tyn). The search works like this. * Find all instances I that match the target constraint; that is, the target constraint is a substitution instance of I. These instance declarations are the candidates. * Find all non-candidate instances that unify with the target constraint. Such non-candidates instances might match when the target constraint is further instantiated. If all of them are incoherent, proceed; if not, the search fails. * Eliminate any candidate IX for which both of the following hold: * There is another candidate IY that is strictly more specific; that is, IY is a substitution instance of IX but not vice versa. * Either IX is overlappable or IY is overlapping. * If only one candidate remains, pick it. Otherwise if all remaining candidates are incoherent, pick an arbitrary candidate. Otherwise fail. }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:25 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by andreas.abel): Quoting from the spec: * Eliminate any candidate IX for which both of the following hold: * There is another candidate IY that is strictly more specific; that is, IY is a substitution instance of IX but not vice versa. * Either IX is overlappable or IY is overlapping. Mathematically, this makes a lot of sense. But put on the hat of library writers, and users, and users that don't rtfm. Looking out from under this hat, the one may always wonder whether one should make one's generic instances OVERLAPPABLE or not. If I create a library with type class Bla and {{{ instance Bla a => Bla [a] }}} I could be a nice library writer and spare my users from declaring their Bla String instances as OVERLAPPING, so I'd write {{{ instance {-# OVERLAPPABLE #-} Bla a => Bla [a] }}} Or maybe that would be malicious? I think the current proposal is too sophisticated. There are no convincing examples given in the discussion so far that demonstrate where this sophistication pays off in practice. Keep in mind that 99% of the Haskell users will never study the instance resolution algorithm or its specification, but just flip on/off pragmas until their code goes through. [At least that was my approach: whenever GHC asks for one more LANGUAGE pragma, just throw it in.] -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:26 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas
-------------------------------------+-------------------------------------
Reporter: simonpj | Owner: diatchki
Type: feature | Status: new
request | Milestone:
Priority: normal | Version: 7.8.2
Component: Compiler | Keywords:
Resolution: | Architecture: Unknown/Multiple
Operating System: | Difficulty: Unknown
Unknown/Multiple | Blocked By:
Type of failure: | Related Tickets:
None/Unknown |
Test Case: |
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
Comment (by Simon Peyton Jones

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas
-------------------------------------+-------------------------------------
Reporter: simonpj | Owner: diatchki
Type: feature | Status: new
request | Milestone:
Priority: normal | Version: 7.8.2
Component: Compiler | Keywords:
Resolution: | Architecture: Unknown/Multiple
Operating System: | Difficulty: Unknown
Unknown/Multiple | Blocked By:
Type of failure: | Related Tickets:
None/Unknown |
Test Case: |
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
Comment (by Simon Peyton Jones

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonpj): So what remains now is to decide about the behaviour of "incoherent". Here is a possible re-draft: {{{ Suppose that, in some client module, we are searching for an instance of the target constraint (C ty1 .. tyn). The search works like this. * Find all instances I that match the target constraint; that is, the target constraint is a substitution instance of I. These instance declarations are the candidates. * Eliminate any candidate IX for which both of the following hold: * There is another candidate IY that is strictly more specific; that is, IY is a substitution instance of IX but not vice versa. * Either IX is overlappable or IY is overlapping. * If only one candidate remains, pick it. Otherwise if all remaining candidates are incoherent, pick an arbitrary candidate. Otherwise fail. * If the selected candidate (from the previous step) is not incoherent, then find all non-candidate instances that unify with the target constraint. Such non-candidates instances might match when the target constraint is further instantiated. If all of them are incoherent, proceed; if not, the search fails. * Return the selected candidate. }}} The difference is that we are slightly more permissive in the case of incoherent instances: if the selected candidate is incoherent, then we ignore all unifying ones. That would allow us to write {{{ instance {-# INCOHERENT #-} Typeable (n::Nat) where ... instance (Typeable f, Typeable a) => Typeable (f a) where ... }}} as was proposed in the original Description of this ticket, rather than making the `(f a)` instance incoherent. I think this would affect practically no one, and would accept a few more programs. So I don't think it's very controversial. Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:29 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by dterei): I'd like to propose we remove the `OVERLAPS` pragma. Why? == Long Version == https://ghc.haskell.org/trac/ghc/wiki/SafeHaskell/NewOverlappingInstances#Ne... --a.k.aInstanceSpecificPragmas == Short Version (kind-of) == The security implications of OVERLAPPABLE vs. OVERLAPPING are fairly different. Remember, in Safe Haskell we apply a policy of only allowing instances from a module M compiled with `-XSafe` to overlap other instances from module M. If it overlaps (and is the most specific overlap) instances from modules other than M then we don't allow this to succeed. This is done to ensure that untrusted code compiled with `-XSafe` can't alter the behavior of existing code, some of which may be part of the TCB and security critical. Brining the new finer grained pragmas into the story we get the following: * OVERLAPPABLE is the programmer communicating that they can be overlapped, an open instance if you will. We want to relax the above restriction and allow instances from `-XSafe` modules to overlap instances from their own module AND instances declared OVERLAPPABLE that reside in any module. * OVERLAPPING is the programming simply declaring they may overlap less specific instances. We want to keep the above restriction for these instances. That is, a instance I1 from a `-XSafe` module M won't be able to overlap as the most specific instance, a instance I2 from another module if I2 is marked as OVERLAPPING. This distinction enables new encodings in Safe Haskell by allowing security library authors to distinguish how untrusted code can overlap their instances. In some way giving them open vs closed instances. This distinction is subtle and important. Having a pragma OVERLAPS that implies both glosses over this and will encourage developers to use this without much thought. ## Safe Inference We can also safely infer a module that only has OVERLAPPABLE instances as safe, while ones that contain OVERLAPPING or OVERLAPS instances must be regarded as unsafe since there is a difference in semantics of these pragmas under Safe vs Unsafe. So we also have an advantage if developers are more specific about what they want, than just defaulting to OVERLAPS. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:30 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by jrp): The ghc build system itself still uses -XOverlappingInstances and so presumably needs to be updated too. {{{ "rm" -f libraries/haskeline/dist- install/build/.depend-v-dyn-p-dyn.haskell.tmp "inplace/bin/ghc-stage1" -M -static -O -H64m -package-name haskeline-0.7.1.2 -hide-all-packages -i -ilibraries/haskeline/. -ilibraries/haskeline/dist-install/build -ilibraries/haskeline/dist- install/build/autogen -Ilibraries/haskeline/dist-install/build -Ilibraries/haskeline/dist-install/build/autogen -Ilibraries/haskeline/includes -optP-DUSE_GHC_ENCODINGS -optP-DTERMINFO -optP-include -optPlibraries/haskeline/dist- install/build/autogen/cabal_macros.h -package base-4.7.1.0 -package bytestring-0.10.4.0 -package containers-0.5.5.1 -package directory-1.2.1.0 -package filepath-1.3.0.2 -package terminfo-0.4.0.0 -package transformers-0.4.1.0 -package unix-2.7.0.2 -Wall -XHaskell98 -XForeignFunctionInterface -XRank2Types -XFlexibleInstances -XTypeSynonymInstances -XFlexibleContexts -XExistentialQuantification -XScopedTypeVariables -XGeneralizedNewtypeDeriving -XMultiParamTypeClasses -XOverlappingInstances -XUndecidableInstances -XCPP -XDeriveDataTypeable -XPatternGuards -O2 -no-user-package-db -rtsopts -odir libraries/haskeline/dist-install/build -hidir libraries/haskeline/dist- install/build -stubdir libraries/haskeline/dist-install/build -dep- makefile libraries/haskeline/dist- install/build/.depend-v-dyn-p-dyn.haskell.tmp -dep-suffix "" -dep-suffix "dyn_" -dep-suffix "p_" -dep-suffix "dyn_" -include-pkg-deps libraries/haskeline/./System/Console/Haskeline.hs libraries/haskeline/./System/Console/Haskeline/Completion.hs libraries/haskeline/./System/Console/Haskeline/MonadException.hs libraries/haskeline/./System/Console/Haskeline/History.hs libraries/haskeline/./System/Console/Haskeline/IO.hs libraries/haskeline/./System/Console/Haskeline/Backend.hs libraries/haskeline/./System/Console/Haskeline/Backend/WCWidth.hs libraries/haskeline/./System/Console/Haskeline/Command.hs libraries/haskeline/./System/Console/Haskeline/Command/Completion.hs libraries/haskeline/./System/Console/Haskeline/Command/History.hs libraries/haskeline/./System/Console/Haskeline/Command/KillRing.hs libraries/haskeline/dist- install/build/System/Console/Haskeline/Directory.hs libraries/haskeline/./System/Console/Haskeline/Emacs.hs libraries/haskeline/./System/Console/Haskeline/InputT.hs libraries/haskeline/./System/Console/Haskeline/Key.hs libraries/haskeline/./System/Console/Haskeline/LineState.hs libraries/haskeline/./System/Console/Haskeline/Monads.hs libraries/haskeline/./System/Console/Haskeline/Prefs.hs libraries/haskeline/./System/Console/Haskeline/RunCommand.hs libraries/haskeline/./System/Console/Haskeline/Term.hs libraries/haskeline/./System/Console/Haskeline/Command/Undo.hs libraries/haskeline/./System/Console/Haskeline/Vi.hs libraries/haskeline/./System/Console/Haskeline/Recover.hs libraries/haskeline/dist- install/build/System/Console/Haskeline/Backend/Posix.hs libraries/haskeline/./System/Console/Haskeline/Backend/Posix/Encoder.hs libraries/haskeline/./System/Console/Haskeline/Backend/DumbTerm.hs libraries/haskeline/./System/Console/Haskeline/Backend/Terminfo.hs on the commandline: Warning: -XOverlappingInstances is deprecated: instead use per-instance pragmas OVERLAPPING/OVERLAPPABLE/OVERLAPS }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:31 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonpj): David, I don't think it's feasible to remove `OVERLAPS` at the moment, unless you can amass some real support for it. * Main reason: people have argued precisely the opposite: that `OVERLAPPING` and `OVERLAPPABLE` are too complicated, and they should be removed in favour of just `OVERLAPS`. In principle I like the idea of forcing people to be explicit, but I think it's bridge too far. * Tiresome reason: the parser isn't up to parsing two pragmas; currently `{-# OVERLAPPING, OVERLAPPABLE #-}` isn't allowed. Someone would have to fix that. Of course, if `-XSafe` is on, you can modify the behaviour if you like. So if you want to propose something along those lines, go ahead. Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:32 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by dterei): I noticed Andreas Abel on the mailing list objected to removing `OVERLAPS` but otherwise felt people were silent on the issue. We don't want to just make a chance in `-XSafe` as ideally `-XSafe` and GHC Haskell are as close as possible, otherwise the long term viability of Safe Haskell isn't good. I'll see what support I can rally or alternatives come up. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:33 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by carter): I'd be willing to do the leg work for augmenting the pragma parser, since I need to get familiar with the pragma parser anyways for some of my own work. (if of course, that would enable a desired design choice, if not that don't mind me) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:34 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas
-------------------------------------+-------------------------------------
Reporter: simonpj | Owner: diatchki
Type: feature | Status: new
request | Milestone:
Priority: normal | Version: 7.8.2
Component: Compiler | Keywords:
Resolution: | Architecture: Unknown/Multiple
Operating System: | Difficulty: Unknown
Unknown/Multiple | Blocked By:
Type of failure: | Related Tickets:
None/Unknown |
Test Case: |
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
Comment (by Simon Peyton Jones

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: closed request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: fixed | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Changes (by simonpj): * status: new => closed * resolution: => fixed Comment: I have finally done the INCOHERENT thing. I'll close this ticket. There are some loose ends which I'll list here: * David, if you want to open a new ticket for OVERLAPS, by all means do so, if you think you've got a good proposal with user support. * I'd like to make `-XUndecideableInstances` a per-instance pragma, instead of a module-wide LANGUAGE flag. That would be consistent with this `OVERLAPPABLE` stuff. Anyone want to do that? * At least one person suggested that there should be a LANGUAGE pragma that switches on recognition of the per-instance pragmas. So `{-# OVERLAPPABLE #-}` is only honoured if you have `-XHonourOverlappingInstnaces` or something. Personally I think this is too much, but users may differ! Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:36 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas -------------------------------------+------------------------------------- Reporter: simonpj | Owner: diatchki Type: feature | Status: closed request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: fixed | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by hvr): Fyi (& hoping you may give it a look) somewhat related to this ticket is Phab:D377 which is about removing `-XOverlappingInstances` from `Data.Typeable.*` -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9242#comment:37 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas
-------------------------------------+-------------------------------------
Reporter: simonpj | Owner: diatchki
Type: feature | Status: closed
request | Milestone:
Priority: normal | Version: 7.8.2
Component: Compiler | Keywords:
Resolution: fixed | Architecture: Unknown/Multiple
Operating System: | Difficulty: Unknown
Unknown/Multiple | Blocked By:
Type of failure: | Related Tickets:
None/Unknown |
Test Case: |
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
Comment (by Herbert Valerio Riedel
participants (1)
-
GHC