
Brandon,
Hm. Seems to me that (with TypeFamilies and FlexibleContexts)
h :: (x ~ y, Eval (y -> Int)) => (x -> Int) -> (y -> Int) -> Int
should do that, but ghci is telling me it isn't (substituting Eq for Eval for the nonce):
Prelude> let h :: (x ~ y, Eq (y -> Int)) => (x -> Int) -> (y -> Int) -> Int; h = undefined Prelude> :t h h :: (Eq (x -> Int)) => (x -> Int) -> (x -> Int) -> Int
Bleah. (as if it weren't obvious) I still don't quite grok this stuff....
Well... x ~ y kind of implies that x could replace y within the scope of the constraint: it's like one of the first thing I would expect to follow from a notion of equality. ;-) But actually if you push the constraint inward, into the type so to say, you actually get quite close to Janis' and David's solution. Cheers, Stefan