How does the ambiguity check work

Jan van Brügge jan at
Fri Sep 27 16:37:47 UTC 2019

Hi lovely people,

I am currently trying to wrap my head around the ambiguity check in GHC.
In particular for those two instances:


class RowEquality where
    rowEqual :: Bool

instance (1 ~ 2) => RowEquality where
    rowEqual = True

instance ( ("foo" ::: Int & RNil) ~ ("bar" ::: String & "foo" ::: Int &
RNil) ) => RowEquality where
    rowEqual = True

I would expect them to behave the same but the second one throws an
error when trying to compile the module (*before* using `rowEqual` -
that would obviously throw a type error in both cases):

Test.hs:24:10: error:
    • Could not deduce: (| "foo" :: Int |)
                        ~ (| "bar" :: [Char], "foo" :: Int |)
      from the context: (("foo" ::: Int) & RNil)
                        ~ (("bar" ::: String) & (("foo" ::: Int) & RNil))
        bound by an instance declaration:
                   ((("foo" ::: Int) & RNil)
                    ~ (("bar" ::: String) & (("foo" ::: Int) & RNil))) =>
        at Test.hs:24:10-94
    • In the ambiguity check for an instance declaration
      To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
      In the instance declaration for 'RowEquality

I have troubles to understand why GHC tries to solve the constraint
there. I worked through `checkAmbiguity` in `TcValidity` and the
function it calls, but from what I can see is that it also tries to
solve the `(1 ~ 2)` and fails in the same way as with the second one. I
cannot find any reason why the two are treated differently.

Thank you

More information about the ghc-devs mailing list