I wonder if there is a deeper reason why we cannot abstract from class classes (or can we?).
For example, when we have
fzip :: (forall a.[a] -> [a]) -> [b] -> [c] -> [(b,c)] fzip f xs ys = zip (f xs) (f ys)
then we can say that
fzip (drop 42) [1..100] ['a'..'z'] fzip reverse [1..100] ['a'..'z']
etc. But we can’t
fzip (map succ) [1..100] ['a'..'z']
which we can fix with:
ezip :: (Enum b, Enum c) => (forall a.Enum a => [a] -> [a]) -> [b] -> [c] -> [(b,c)] ezip f xs ys = zip (f xs) (f ys)
as well as we can fix
fzip (map (5*)) [1..100] [1.5, 2.3, 4.7]
with
nzip :: (Num b, Num c) => (forall a.Num a => [a] -> [a]) -> [b] -> [c] -> [(b,c)] nzip f xs ys = zip (f xs) (f ys)
But doesn't it bother us that we can't include ezip and nzip something like:
gzip :: (gb, gc) => (forall a. ga => [a] -> [a]) -> [b] -> [c] -> [(b,c)]
although the code is absolutely identical, right down to the class name? Or can we somehow?
Interestingly, when instances were only records containing functions, this would be easily possible.
source share