From 1f8b341a88b6b60935b0ce80b59ed6e356b8cfbf Mon Sep 17 00:00:00 2001 From: simonpj Date: Fri, 26 Nov 2004 13:42:39 +0000 Subject: [PATCH] [project @ 2004-11-26 13:42:37 by simonpj] Document overlapping instances --- ghc/docs/users_guide/flags.xml | 18 +++-- ghc/docs/users_guide/glasgow_exts.xml | 139 ++++++++++++--------------------- 2 files changed, 63 insertions(+), 94 deletions(-) diff --git a/ghc/docs/users_guide/flags.xml b/ghc/docs/users_guide/flags.xml index ab61bd4..d4e1fc6 100644 --- a/ghc/docs/users_guide/flags.xml +++ b/ghc/docs/users_guide/flags.xml @@ -445,18 +445,24 @@ - - Enable arrow notation extension - dynamic - - - Enable undecidable instances dynamic + + Enable incoherent instances + dynamic + + + + + Enable arrow notation extension + dynamic + + + n set the limit for context reduction static diff --git a/ghc/docs/users_guide/glasgow_exts.xml b/ghc/docs/users_guide/glasgow_exts.xml index a3e1d01..8d3595b 100644 --- a/ghc/docs/users_guide/glasgow_exts.xml +++ b/ghc/docs/users_guide/glasgow_exts.xml @@ -1701,96 +1701,59 @@ means Overlapping instances -In general, instance declarations may not overlap. The two instance -declarations - - - - instance context1 => C type1 where ... - instance context2 => C type2 where ... - - -"overlap" if type1 and type2 unify. - - -However, if you give the command line option --fallow-overlapping-instances -option then overlapping instance declarations are permitted. -However, GHC arranges never to commit to using an instance declaration -if another instance declaration also applies, either now or later. - - - - - - EITHER type1 and type2 do not unify - - - - - - OR type2 is a substitution instance of type1 -(but not identical to type1), or vice versa. - - - -Notice that these rules - - - - - make it clear which instance decl to use -(pick the most specific one that matches) - - - - - - - do not mention the contexts context1, context2 -Reason: you can pick which instance decl -"matches" based on the type. - - - - -However the rules are over-conservative. Two instance declarations can overlap, -but it can still be clear in particular situations which to use. For example: - - instance C (Int,a) where ... - instance C (a,Bool) where ... - -These are rejected by GHC's rules, but it is clear what to do when trying -to solve the constraint C (Int,Int) because the second instance -cannot apply. Yell if this restriction bites you. - - -GHC is also conservative about committing to an overlapping instance. For example: - - class C a where { op :: a -> a } - instance C [Int] where ... - instance C a => C [a] where ... - - f :: C b => [b] -> [b] - f x = op x - -From the RHS of f we get the constraint C [b]. But -GHC does not commit to the second instance declaration, because in a particular -call of f, b might be instantiate to Int, so the first instance declaration -would be appropriate. So GHC rejects the program. If you add -GHC will instead silently pick the second instance, without complaining about +In general, GHC requires that that it be unambiguous which instance +declaration +should be used to resolve a type-class constraint. This behaviour +can be modified by two flags: +-fallow-overlapping-instances + +and +-fallow-incoherent-instances +, as this section discusses. + +When GHC tries to resolve, say, the constraint C Int Bool, +it tries to match every instance declaration against the +constraint, +by instantiating the head of the instance declaration. For example, consider +these declarations: + + instance context1 => C Int a where ... -- (A) + instance context2 => C a Bool where ... -- (B) + instance context3 => C Int [a] where ... -- (C) + instance context4 => C Int [Int] where ... -- (D) + +The instances (A) and (B) match the constraint C Int Bool, but (C) and (D) do not. When matching, GHC takes +no account of the context of the instance declaration +(context1 etc). +GHC's default behaviour is that exactly one instance must match the +constraint it is trying to resolve. +It is fine for there to be a potential of overlap (by +including both declarations (A) and (B), say); an error is only reported if a +particular constraint matches more than one. + + + +The flag instructs GHC to allow +more than one instance to match, provided there is a most specific one. For +example, the constraint C Int [Int] matches instances (A), +(C) and (D), but the last is more specific, and hence is chosen. If there is no +most-specific match, the program is rejected. + + +However, GHC is conservative about committing to an overlapping instance. For example: + + f :: [b] -> [b] + f x = ... + +Suppose that from the RHS of f we get the constraint +C Int [b]. But +GHC does not commit to instance (C), because in a particular +call of f, b might be instantiate +to Int, in which case instance (D) would be more specific still. +So GHC rejects the program. If you add the flag , +GHC will instead pick (C), without complaining about the problem of subsequent instantiations. - -Regrettably, GHC doesn't guarantee to detect overlapping instance -declarations if they appear in different modules. GHC can "see" the -instance declarations in the transitive closure of all the modules -imported by the one being compiled, so it can "see" all instance decls -when it is compiling Main. However, it currently chooses not -to look at ones that can't possibly be of use in the module currently -being compiled, in the interests of efficiency. (Perhaps we should -change that decision, at least for Main.) - -- 1.7.10.4