The compiler only warns for overlapping instances when solving. This is actually a bug, as illustrated by the following example, which prints false, but gives no overlap warning:
class IsInt a where
isInt :: a -> Boolean
instance intIsInt :: IsInt Int where
isInt _ = true
instance isn'tInt :: IsInt a where
isInt _ = false
class F a b | a -> b where
f :: a -> b
instance fInt :: F Int Int where
f = id
main = logShow (isInt (f 1))
The problem is that the type of the call to isInt is not determined, since the F constraint gets solved later. Therefore we pick the isn'tInt instance, which is wrong.
In order to commit to isn'tInt, we must know that a can never become Int (apartness). Alternatively, we could try to warn at the definition site.
cc @LiamGoodacre You will probably find this interesting.
The compiler only warns for overlapping instances when solving. This is actually a bug, as illustrated by the following example, which prints
false, but gives no overlap warning:The problem is that the type of the call to
isIntis not determined, since theFconstraint gets solved later. Therefore we pick theisn'tIntinstance, which is wrong.In order to commit to
isn'tInt, we must know thatacan never becomeInt(apartness). Alternatively, we could try to warn at the definition site.cc @LiamGoodacre You will probably find this interesting.