What I want to do is define a NextClass type class, which will allow me to (given a value x) get the next value of x for all types that are instances of the NextClass. To use the + operator, I need the Num a class constraint for Int.

However, GHC gives me the following error:

Could not deduce (Ctxt f0 a) arising from a use of `next'
from the context (NextClass a)
bound by the type signature for n :: NextClass a => a -> a
In the expression: next v
In an equation for `n': n v = next v

I suspect that GHC is telling me it does not have enough information to determine which constraint family instance to use.

Could someone explain what I am doing wrong here. Is this a correct use of constraint families?

1 Answer
1

There's a few odd things going on in your definition. First of all, the class variable f is never mentioned in the type of the (only) class method next. How is the compiler supposed to choose which instance of the type class to use? I'm going to assume you meant this:

The next oddity is that Int already has a Num instance, so this isn't much of a constraint. But let's leave that aside for now (since it doesn't affect the error we get) and just look at the new error:

test.hs:15:7:
Could not deduce (Ctxt a) arising from a use of `next'
from the context (NextClass a)
bound by the type signature for n :: NextClass a => a -> a
at test.hs:15:1-12
In the expression: next v
In an equation for `n': n v = next v

Actually, this error looks quite sensible: the whole point of the constraint is that having an instance for NextClass a isn't enough; we must also have an instance of Ctxt a. So we can fix up the type signature:

n :: (NextClass a, Ctxt a) => a -> a
n v = next v

...and then it compiles. The final oddity is that this is a particularly degenerate use of constraint kinds, since this simpler code is essentially equivalent:

Thanks Daniel, I changed my code to use the instance Num Int => NextClass Int where .... Is this the idiomatic way to write this type of code in Haskell?
–
Rouan van DalenJun 12 '12 at 7:40

@RouanvanDalen Well, the idiomatic way is either instance NextClass Int where ... with no trivial constraints or newtype SuccNext a = SuccNext a; instance Num a => NextClass (SuccNext a) where ... with a polymorphic type (and a newtype to prevent spurious overlapping).
–
Daniel WagnerJun 12 '12 at 8:08

Good stuff. I have to read up more on type classes again :)
–
Rouan van DalenJun 12 '12 at 8:22