
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