diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2013-01-08 08:26:40 +0000 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2013-01-08 08:26:40 +0000 |
commit | 97db0edc4e637dd61ec635d1f9b6b6dd25ad890c (patch) | |
tree | 72458c158b4d013fc05c8f3b22499aa0bfee8147 /compiler/ghc.cabal.in | |
parent | afe9a3b0f1a28c364e8574c7d26962f89dd9806e (diff) | |
download | haskell-97db0edc4e637dd61ec635d1f9b6b6dd25ad890c.tar.gz |
Re-engineer the ambiguity test for user type signatures
Two main changes. First, re-engineer the ambiguity test. Previously
TcMType.checkAmbiguity used a rather syntactic test to detect some
types that are certainly ambiguous. But a much easier test is available,
and it is used for inferred types in TcBinds. Namely
<type> is ambiguous
iff
<type> `TcUnify.isSubType` <type>
fails to hold, where "isSubType" means "is provably more polymorphic than".
Example:
C a => Int
is ambiguous, because isSubType instantiates the (C a => Int)
to (C alpha => Int) and then tries to deduce (C alpha) from (C a). This is
Martin Sulzmann's definition of ambiguity. (Defn 10 of "Understanding
functional dependencies via constraint handling rules", JFP.)
This change is neat, reduces code, and correctly rejects more programs.
However is *is* just possible to have a useful program that would be
rejected. For example
class C a b
f :: C Int b => Int -> Int
Here 'f' would be rejected as having an ambiguous type. But it is
just possible that, at a *call* site there might be an instance
declaration instance C Int b, which does not constrain 'b' at all.
This is pretty strange -- why is 'b' overloaded at all? -- but it's
possible, so I also added a flag -XAllowAmbiguousTypes that simply
removes the ambiguity check. Let's see if anyone cares. Meanwhile
the earlier error report will be useful for everyone else.
A handful of regression tests had to be adjusted as a result, because
they used ambiguous types, somewhat accidentally.
Second, split TcMType (already too large) into two
* TcMType: a low-level module dealing with monadic operations like
zonking, creating new evidence variables, etc
* TcValidity: a brand-new higher-level module dealing with
validity checking for types: checkValidType, checkValidInstance,
checkFamInstPats etc
Apart from the fact that TcMType was too big, this allows TcValidity
to import TcUnify(tcSubType) without causing a loop.
Diffstat (limited to 'compiler/ghc.cabal.in')
-rw-r--r-- | compiler/ghc.cabal.in | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/compiler/ghc.cabal.in b/compiler/ghc.cabal.in index 44d0952b33..47225b5164 100644 --- a/compiler/ghc.cabal.in +++ b/compiler/ghc.cabal.in @@ -362,6 +362,7 @@ Library TcHsType TcInstDcls TcMType + TcValidity TcMatches TcPat TcRnDriver |