
Marcin 'Qrczak' Kowalczyk
But if contexts-on-datatypes worked correctly, data Set a = Ord a => .... then even the "real" map from Data.Set: map :: (Ord a, Ord b) => (a -> b) -> Set a -> Set b could be an instance method of Functor.
fmap ($0) . fmap const :: Functor f => f a -> f a
When applied to Set Int, how would it represent the intermediate set of functions? Or if it was disallowed, on what basis?
Clever example. The intermediate set is :: Set (Int->b->Int), which does not satisfy the construction constraint (Ord a) => Set a. But persuading the type system to reject this is tricky I agree. I'm not a type hacker, so I don't know how to go about it. I suppose if the complete set of class instances for the entire program were known, then you could have a negation predicate, asserting that the intermediate type (Int->b->Int) does not have an instance of Ord, and somehow record this in the type environment fmap ($0) . fmap const :: (Functor f, not Ord a) => f a -> f a But then, there are a whole host of classes that (->) is not an instance of, so this is pretty useless because the constraints will grow enormously for little benefit. In short, I suppose the reason contexts-on-datatypes are as they are currently, is because no-one yet knows how to solve your example. Regards, Malcolm