Question

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.

Was it helpful?

Solution

(MonoTraversable a0, Num (Element a0)) => a0 -> Int looks like it ought to work, qualifying the type family instance.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top