Skip to content

Commit c22e716

Browse files
authored
Add documentation for GHC-43085 (OverlappingInstances) (#546)
1 parent ab7213f commit c22e716

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
title: Overlapping Instances
3+
summary: Multiple type class instances are resolved for a single type class method call.
4+
severity: error
5+
introduced: 9.6.1
6+
---
7+
8+
Type class methods that make use of
9+
[overlapping instances](https://downloads.haskell.org/ghc/9.12.1/docs/users_guide/exts/instances.html#overlapping-instances)
10+
lead may lead to an error because the resolved candidates would lead to indeterministic program behavior.
11+
12+
We can solve this by annotating the instances with the `{-# OVERLAPS #-}`, `{-# OVERLAPPING #-}`, `{-# OVERLAPPABLE #-}` and `{-# INCOHERENT #-}` pragma.
13+
The former three can only be used if instances are *strictly more specific* than one another, i.e. the type of an instance can be substituted for the type of another instance.
14+
15+
Note that `{-# INCOHERENT #-}` still leads to indeterministic behavior and thus should be used with caution.
16+
17+
~~~
18+
before/Overlapping.hs:18:19: error: [GHC-43085]
19+
• Overlapping instances for Formatter (Maybe Int)
20+
arising from a use of ‘format’
21+
Matching instances:
22+
instance Formatter (Maybe Int)
23+
-- Defined at before/Overlapping.hs:13:10
24+
instance Formatter a => Formatter (Maybe a)
25+
-- Defined at before/Overlapping.hs:9:10
26+
• In the second argument of ‘($)’, namely
27+
‘format (Nothing :: Maybe Int)’
28+
In the expression: putStrLn $ format (Nothing :: Maybe Int)
29+
In an equation for ‘main’:
30+
main = putStrLn $ format (Nothing :: Maybe Int)
31+
|
32+
18 | main = putStrLn $ format (Nothing :: Maybe Int)
33+
| ^^^^^^
34+
~~~
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module Overlapping where
2+
3+
class Formatter a where
4+
format :: a -> String
5+
6+
instance Formatter Int where
7+
format = show
8+
9+
instance {-# OVERLAPPABLE #-} (Formatter a) => Formatter (Maybe a) where
10+
format (Just x) = format x
11+
format Nothing = ""
12+
13+
instance {-# OVERLAPS #-} Formatter (Maybe Int) where
14+
format (Just x) = format x
15+
format Nothing = "NaN"
16+
17+
main :: IO ()
18+
main = putStrLn $ format (Nothing :: Maybe Int)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module Overlapping where
2+
3+
class Formatter a where
4+
format :: a -> String
5+
6+
instance Formatter Int where
7+
format = show
8+
9+
instance (Formatter a) => Formatter (Maybe a) where
10+
format (Just x) = format x
11+
format Nothing = ""
12+
13+
instance Formatter (Maybe Int) where
14+
format (Just x) = format x
15+
format Nothing = "NaN"
16+
17+
main :: IO ()
18+
main = putStrLn $ format (Nothing :: Maybe Int)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
title: Overlapping instances for Maybe
3+
---
4+
5+
Here, the two instances `Formatter (Maybe a)` and `Formatter (Maybe Int)` are overlapping.
6+
Since the latter is more specific, we can solve this by annotating the instances with the `{-# OVERLAPPABLE #-}` and `{-# OVERLAPS #-}`.

0 commit comments

Comments
 (0)