After studying haskell as a hobby for some time now, I'm still "thinking OOP"... In particular I still don't find myself comfortable with Type Classes.
Extending Type Classes
Every time I use them I "feel" the need to write a Type Class that extends another one (as if they where c++ classes). But if you want to extend a Type Class you just need a plain function. Like in:
class T1 a where
m1 :: a -> Int
doubleM1 :: (T1 a) => a -> Int
doubleM1 x = 2 * m1 x
Of course if you can alter the Type Class definition itself you can add doubleM1' to the Type Class itself like in:
class T1 a where
m1 :: a -> Int
doubleM1' :: a -> Int
doubleM1' x = 2 * m1 x
This second form is more powerful because you can write different implementations for different instances, if so you desire. That is not always a good thing, see:
instance T1 Double where
doubleM1' x = 3 * m1 x
m1 = round
My Question
Suppose I have two Type Classes (e.g. they are not not my own Type Classes i.e. I can't modify them)
class T1 a where
m1 :: a -> Int
class T2 a where
m2 :: a -> Int
Can I write a Type Class member (or a plain function) that accepts any instance of T1 or T2 and gives back an Int? For instance like in:
class T a where
m :: => a -> Int
instance T AnyTypeThatHasAnInstanceForT1 where
m = m1
instance T AnyTypeThatHasAnInstanceForT2 where
m = m2
I think my OOP trained brain wants to use overloading in order to avoid writing all my instances twice. What is an idiomatic haskell way of solving such problem?