This code compiles fine:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,
UndecidableInstances, FlexibleContexts, EmptyDataDe
It means that you aren't allowed to use type synomym families when declaring type instances. See the section "Type families and instance declarations" of the GHC manual.
The only way you can fix it is to refactor so as to not need it somehow.
Rec
is not a type constructor; it's a type function. Maybe you can use it only in the type of a value of type definition, not in a class declaration? I'm guessing wildly here; I don't understand all the rules for type families.
I don't know how to fix it, but some things to try include:
Get rid of class Sel and just define type family Res a s b :: *
. Use type instance
instead of the class mechanism.
It's barely possible that making type Rec
injective using data
will help, but I don't think so.
Cut back to the smallest number of language extensions that could possibly work—it will make it easier for others to help you, and it might help the compiler as well.
Type families are one-way: you can expand Rec a
to its computed type, but you cannot (uniquely) go from the expansion back to Rec a
. This makes applications of type functions unsuitable for instance signatures, as they can never trigger the instance to apply.
You could try instead:
instance Rec a ~ reca => Sel a s (b->(c,reca))
This means something else: it says any function b -> (c, reca)
is an instance, and then when it has irrevocably matched, the compiler checks that Rec a ~ reca
. But this might be good enough to do want in your case.