Now I would like to generalise 'foo' and 'bar' to 'bla' so that I can write:

 testBla1 = bla fromInteger 1  :: (Int, Float)
 testBla2 = bla read       "1" :: (Int, Float)

My question is how to define 'bla'.

I can write:

> bla :: (forall b. a -> b) -> a -> (c, d)
> bla f x = (f x, f x)

But then 'testBla1' gives the following expected error:

 Could not deduce (Num b) from the context ()
   arising from a use of `fromInteger'

[...]

So, somehow I need to quantify over the type class.

 bla :: forall cls. (cls c, cls d) => (forall b. cls b => a -> b) -> a -> (c, d)

But this isn't legal.

Is there another way of defining 'bla'?

The simple, from-the-gut answer involves the enumeration of all the classes that you need in the context.

> bla :: (Read c, Read d, Num c, Num d) => (forall b. (Read b, Num b) => a -> b) -> a -> (c, d)
> bla f x = (f x, f x)

But perhaps you're looking for potentially unknown classes?

Sean