[Haskell-beginners] Ambiguous type variables

Brent Yorgey byorgey at seas.upenn.edu
Mon Mar 17 20:02:21 UTC 2014


On Mon, Mar 17, 2014 at 12:14:31PM -0700, Dennis Raddle wrote:
> 
> The error is
> 
> Ambiguous type variables 'd0', 'c0' in the constraint:
>   (Bt d0 c0 memo) arising from a use of 'newMemo'
> 
> class Bt d c memo | d -> c, d -> memo where
> 
>   newMemo :: memo

This is because given a use of 'newMemo', the compiler will be able to
infer the type 'memo' from the context in which it is used, but there
is no way for it to infer the types d and c.  Hence they are
ambiguous.  There could be overlapping instances like

  instance Bt Int  Int    Char ...
  instance Bt Bool String Char ...

so knowing memo=Char does not tell us what d and c are.  (Note the
compiler still refuses to make a choice even if there is only one
matching instance in scope, because new instances could always be
added in another module.)

I can think of several possible solutions:

  1. Add some functional dependencies memo -> d, memo -> c.  This
     would "solve" the error though it is probably not what you want.

  2. Add some 'dummy' arguments to newMemo (and other functions with a
     similar problem), like

       newMemo :: Proxy d -> memo

     However, this is a bit annoying to call since it requires giving
     a Proxy argument with a type signature.

  3. Make Bt a record rather than a type class.  This might actually
     be your best bet.  You have to manually pass around Bt records,
     but you get to fully specify the types involved.

-Brent


More information about the Beginners mailing list