wiki

Overlapping instances

Two instances overlap when a type matches both of their heads[1][2]. Instance resolution is not a backtracking search: GHC matches the constraint against instance heads, ignoring their contexts, and commits to the one that matches[7]. With two candidates and no way to know which is intended, it reports an error rather than guess. The OVERLAPPING and OVERLAPPABLE pragmas resolve the conflict by declaring that the most specific instance wins, which is how a library can treat String specially while still providing an instance for every list[1]. The choice is then made wherever the constraint happens to be solved, so the result can depend on which instances were in scope there, and on whether the type was known; INCOHERENT removes the remaining check. Overlap was used heavily in type-level programming[3], and closed type families now provide ordered matching without it[4].

§ 01

Example

The classic case: [Char] matches both list instances.

{-# LANGUAGE FlexibleInstances #-}
import Data.List (intercalate)
class Pretty a where pp :: a -> String
instance Pretty Char where pp c = [c]
instance Pretty a => Pretty [a] where pp xs = "[" ++ intercalate ", " (map pp xs) ++ "]"
instance Pretty String where pp s = show s -- String = [Char]
main :: IO ()
main = putStrLn (pp "abc")

GHC's error at the use.

noprag.hs:11:18: error:
* Overlapping instances for Pretty String
arising from a use of `pp'
Matching instances:
instance Pretty String -- Defined at noprag.hs:8:10
instance Pretty a => Pretty [a] -- Defined at noprag.hs:7:10
* In the first argument of `putStrLn', namely `(pp "abc")'
In the expression: putStrLn (pp "abc")
In an equation for `main': main = putStrLn (pp "abc")
|
11 | main = putStrLn (pp "abc")

The declarations are accepted; the error appears only when a constraint needs to choose. GHC checks overlap lazily, at the point of use[1].

§ 02

Most specific wins

Marking the general instance OVERLAPPABLE, or the specific one OVERLAPPING, allows the overlap. When several instances match a constraint, GHC picks the one whose head is strictly more specific than all the others, meaning it is a substitution instance of them, and reports an error if there is no such instance[1].

The same instances with pragmas.

{-# LANGUAGE FlexibleInstances #-}
import Data.List (intercalate)
class Pretty a where pp :: a -> String
instance Pretty Char where pp c = [c]
instance Pretty Int where pp = show
instance {-# OVERLAPPABLE #-} Pretty a => Pretty [a] where
pp xs = "[" ++ intercalate ", " (map pp xs) ++ "]"
instance {-# OVERLAPPING #-} Pretty String where
pp s = show s
main :: IO ()
main = do
putStrLn (pp "abc") -- the String instance
putStrLn (pp [1, 2, 3 :: Int]) -- the list instance
putStrLn (pp ["ab", "cd"]) -- list of String: both, nested

Running it.

"abc"
[1, 2, 3]
["ab", "cd"]

In the last line both instances are used: the outer list is not a String, so the general instance applies, and its elements are.

at a known typePretty [Char]Pretty [a]matches, a := CharPretty Stringmore specificOVERLAPPING: the mostspecific instance winsno pragmas: errorat an unknown typePretty [b]Pretty [a]matches, a := bPretty Stringmatches if b = Charcannot commit: the answerdepends on b, so GHC refusesINCOHERENT: picks Pretty [a] anyway
At a known type both list instances match and the more specific one is chosen. At an unknown element type b, the right instance depends on whether b is Char, so GHC refuses to commit unless told to be incoherent.
§ 03

Unknown types

Resolution can be asked to choose before the type is known. Inside a function polymorphic in a, the constraint Pretty [a] matches the general instance, but it would match the String instance if a were Char. Committing to the general instance would give an answer that is wrong for some callers, so GHC rejects the program[1].

A function whose instance depends on its caller.

{-# LANGUAGE FlexibleInstances #-}
import Data.List (intercalate)
class Pretty a where pp :: a -> String
instance Pretty Char where pp c = [c]
instance {-# OVERLAPPABLE #-} Pretty a => Pretty [a] where
pp xs = "[" ++ intercalate ", " (map pp xs) ++ "]"
instance {-# OVERLAPPING #-} Pretty String where
pp s = show s
-- Which instance? It depends on a, which is not known here.
twice :: Pretty a => [a] -> String
twice xs = pp xs ++ pp xs

GHC's error.

poly.hs:14:12: error:
* Overlapping instances for Pretty [a] arising from a use of `pp'
Matching instance:
instance [overlappable] Pretty a => Pretty [a]
-- Defined at poly.hs:7:31
Potentially matching instance:
instance [overlapping] Pretty String -- Defined at poly.hs:9:30
(The choice depends on the instantiation of `a'
To pick the first instance above, use IncoherentInstances
when compiling the other instance declarations)
* In the first argument of `(++)', namely `pp xs'
In the expression: pp xs ++ pp xs
In an equation for `twice': twice xs = pp xs ++ pp xs

The usual fix is to leave the constraint to the caller, writing Pretty [a] => in the signature so that it is solved at the call site where the type is known. Marking an instance INCOHERENT instead tells GHC to pick the general instance anyway and not complain: the function then prints strings as lists of characters even when called at String.

§ 04

Coherence across modules

Overlap is only checked among the instances visible where a constraint is solved. A module that sees only the general instance solves Pretty [Char] with it, and compiled code keeps that choice; a module that also sees the specific instance solves the same constraint differently[1][6]. The same expression, at the same type, then has two meanings in one program.

A library with the general instance, which solves Pretty [Char] in label.

{-# LANGUAGE FlexibleInstances #-}
module General (Pretty (..), label) where
import Data.List (intercalate)
class Pretty a where pp :: a -> String
instance Pretty Char where pp c = [c]
instance {-# OVERLAPPABLE #-} Pretty a => Pretty [a] where
pp xs = "[" ++ intercalate ", " (map pp xs) ++ "]"
-- Pretty [Char] is solved here, where only the general instance exists.
label :: String -> String
label s = "label: " ++ pp s

Another module adds the specific instance.

{-# LANGUAGE FlexibleInstances #-}
module Specific () where
import General
instance {-# OVERLAPPING #-} Pretty String where pp s = show s

A program that uses both.

import General
import Specific ()
main :: IO ()
main = do
putStrLn (pp "abc") -- solved here: the String instance
putStrLn (label "abc") -- solved in General: the list instance

Running it: the same string, printed two ways.

"abc"
label: [a, b, c]

This is the same failure of global uniqueness that orphan instances cause, and the two often occur together, since the specific instance is frequently an orphan. It does not break type safety, but it breaks the property that a class method means the same thing at the same type everywhere, which libraries relying on class laws, such as sets ordered by Ord, depend on[6].

§ 05

Alternatives

Closed type families have ordered equations: GHC tries them from top to bottom, and an equation is used only if no earlier one could apply to the arguments, even after further instantiation[4]. A type-level test such as “is this type Char?” can therefore be written without overlap, and a class indexed by its result dispatches to the right instance.

The String special case with a closed type family.

{-# LANGUAGE DataKinds, TypeFamilies, MultiParamTypeClasses, FlexibleInstances,
FlexibleContexts, UndecidableInstances, ScopedTypeVariables,
KindSignatures, AllowAmbiguousTypes, TypeApplications #-}
import Data.List (intercalate)
import Data.Kind (Type)
-- A closed type family's equations are tried in order, so it can express
-- "Char, or anything else" without overlapping instances.
type family IsChar (a :: Type) :: Bool where
IsChar Char = 'True
IsChar a = 'False
class PrettyList (flag :: Bool) a where ppList :: [a] -> String
instance PrettyList 'True Char where ppList s = show s
instance Pretty a => PrettyList 'False a where ppList xs = "[" ++ intercalate ", " (map pp xs) ++ "]"
class Pretty a where pp :: a -> String
instance Pretty Char where pp c = [c]
instance Pretty Int where pp = show
instance PrettyList (IsChar a) a => Pretty [a] where pp = ppList @(IsChar a)
main :: IO ()
main = do
putStrLn (pp "abc")
putStrLn (pp [1, 2, 3 :: Int])
putStrLn (pp ["ab", "cd"])

Running it.

"abc"
[1, 2, 3]
["ab", "cd"]

Instance chains, proposed by Morris and Jones, build ordered alternatives and explicit failure into the instance language itself[5]. The simplest alternative is a newtype: newtype Quoted = Quoted String with its own instance makes the special treatment a choice made at the call site, visible in the types, rather than an effect of resolution order.

§ 06

Rules

For a constraint , GHC finds all instances whose head matches by one-way matching, ignoring their contexts[1]. Instances that are overlapped by a more specific candidate are discarded if either is marked appropriately. If exactly one non-incoherent candidate remains, it is chosen only if no other instance unifies with without matching it, meaning no instance could apply after further instantiation of type variables; incoherent instances are exempt from this check. Contexts are checked only after the choice, so instance Show a => Pretty a overlaps every other instance of Pretty, whatever the context says.

§ 07

History

Wadler and Blott's type classes of 1989 required instances not to overlap[7]. Overlapping instances were implemented in Gofer and Hugs and surveyed as a design option by Peyton Jones, Jones and Meijer in 1997[2]. GHC's OverlappingInstances and IncoherentInstances extensions applied to whole modules; GHC 7.10 in 2015 replaced them with per-instance pragmas. Overlap was central to early type-level programming such as the HList library of heterogeneous collections[3]. Instance chains in 2010[5] and closed type families in GHC 7.8 in 2014[4] gave ordered alternatives without overlap.

see also

referenced by

further reading

  1. [1]GHC User’s Guide, “Overlapping instances”.
  2. [2]S. Peyton Jones, M. Jones, E. Meijer, “Type classes: an exploration of the design space”, Haskell Workshop (1997).
  3. [3]O. Kiselyov, R. Lämmel, K. Schupke, “Strongly typed heterogeneous collections”, Haskell Workshop (2004).
  4. [4]R. A. Eisenberg, D. Vytiniotis, S. Peyton Jones, S. Weirich, “Closed type families with overlapping equations”, POPL (2014).
  5. [5]J. G. Morris, M. P. Jones, “Instance chains: type class programming without overlapping instances”, ICFP (2010).
  6. [6]E. Z. Yang, “Type classes: confluence, coherence and global uniqueness”, blog post (2014).
  7. [7]P. Wadler, S. Blott, “How to make ad-hoc polymorphism less ad hoc”, POPL (1989).

last updated