[GHC] #9242: Implement {-# OVERLAPPABLE #-} and {-# INCOHERENT #-} pragmas
GHC
ghc-devs at haskell.org
Fri Jun 27 07:45:49 UTC 2014
#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
More information about the ghc-tickets
mailing list