Consider this code:
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module Foo where
class Foo a
class SomeClass a
instance {-# OVERLAPPABLE #-} (Foo a) => SomeClass a
bar :: (SomeClass a) => a -> Int
bar = const 0
foo :: (SomeClass a) => a -> Int
foo t = let x = bar t in x
Here, foo calls bar, and should be able to do so using the SomeClass constraint in its context. Instead, GHC assumes it must do so using the Foo a => SomeClass a instance:
Foo.hs:16:17:
Could not deduce (Foo a) arising from a use of ‘bar’
from the context (SomeClass a)
bound by the type signature for foo :: SomeClass a => a -> Int
at Foo.hs:15:8-32
Possible fix:
add (Foo a) to the context of
the inferred type of x :: Int
or the type signature for foo :: SomeClass a => a -> Int
In the expression: bar t
In an equation for ‘x’: x = bar t
In the expression: let x = bar t in x
There are two ways to fix this:
- In
foo, changinglet x = bar t in xtobar t - Appending the line
instance SomeClass Intto my program
What is going on here? Why is this problem occurring, and why do these fixes work?
This example is, of course, simplified by my actual problem. I encountered it during my work on the Cubix framework for multi-language transformation ( arxiv.org/pdf/1707.04600 ).
My actual problem involves a function with a constraint InjF f IdentL FunctionExpL ("f is a language where identifiers may be used to denote the function in a function call"). I have an (overlappable) instance (FunctionIdent :<: f) => InjF f IdentL FunctionExpL, which the typechecker seizes on, giving me a spurious Could not deduce FunctionIdent :<: f error.
This error persists even when there is an instance InjF Foo IdentL FunctionExpL in scope for a specific Foo, so leftaroundabout's answer, which predicts that that other instance should fix the problem, is not the full story.