Search code examples
haskelltypeclassfunctional-dependencies

Why does this instance fail the coverage condition?


Why does the following instance declaration fail the coverage condition in the absence of UndecidableInstances? It seems that if the functional dependency is satisfied in the context then it is satisfied in the new instance.

{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE UndecidableInstances #-}

class Foo a b | a -> b where

instance (Foo a b, Foo a' b') => Foo (a, a') (b, b') where

If I try to replicate the same thing with a type family there is no problem.

{-# LANGUAGE TypeFamilies #-}

type family Bar a

type instance Bar (a, b) = (Bar a, Bar b)

Solution

  • I believe it's that constraints on instances aren't actually taken into account when selecting an instance. They become additional constraints to be proved at each use site, rather than limiting the applicability of the instance.

    So your instance declaration is kind of equivalent to instance Foo (a, b) (c, d), which rather obviously fails the coverage condition.

    Adding the (Foo a b, Foo a' b') only makes it so that some of the uses of the instance would result in "no such instance" errors, it doesn't actually change the types for which your instance will be selected.