Consider this function:
f :: Num a0 => [a0] -> Int
f = -- Let's leave open what we actually do here.
We want to generalize this function to work not only on lists, but also on Set a
, IntSet a
and others. Basically, we want this function to be defined for any MonoTraversable
that contains Num
elements in it.
Here comes the problem: We need to combine the MonoTraversable
constraint:
f :: MonoTraversable a1 => a1 -> Int
with the Num
constraint:
f :: Num a0 => [a0] -> Int
However, MonoTraversable
is a typeclass, therefore this can't work (several variants of this is what I tried):
f :: Num a0 => MonoTraversable a0 -> Int
From hours of researching I guess it's possible to somehow use RankNTypes
(specifically, a rank 2 polymorphism) for this purpose.
Another failed attempt that might display what I'm aiming for:
f :: Num a0, MonoTraversable a1 => a0 a1 -> Int
However, I just can't find any way how to do it even close to properly. Using GHC extensions is fine for me.
(MonoTraversable a0, Num (Element a0)) => a0 -> Int
looks like it ought to work, qualifying the type family instance.