I'm defining my own complex number data type as a learning exercise, and I've run into trouble overloading abs along with the other members of Num. As far as I know, only one instance definition is allowed per typeclass, but if I could I'd do something like this:
instance Num a => Num (Complex a) where
(+) (Complex ra ia) (Complex rb ib) = Complex (ra + rb) (ia + ib)
(-) (Complex ra ia) (Complex rb ib) = Complex (ra - rb) (ia - ib)
(*) (Complex ra ia) (Complex rb ib) = Complex (ra*rb - ia*ib) (ra*ib + rb*ia)
fromInteger r = Complex (fromInteger r) 0
instance Floating a => Num (Complex a) where
abs (Complex r i) = Complex (sqrt $ r^2 + i^2) 0
or
instance Floating a => Floating (Complex a) where
abs (Complex r i) = Complex (sqrt $ r^2 + i^2) 0
Because none of the members other than abs require Floating types, and I don't want to limit them to only Floating types, but the abs function is super important, and I don't want to unnecessarily exclude it.
Is there some way I can have the functions (+), (-), and (*) work on all numeric types, while still implementing abs?
According to 7.6.3.4. Overlapping instances in the GHC system guide, multiple instances can overlap if they differ on the type constraint(?) outside of the context (eg instance C [a] and instance C [Int]), with the compiler choosing the most specific instance for a given case, but it doesn't mention anything about only the context differing (eg instance C [a] and instance Integral a => C [a]).
Complex a? There exists an alternative hierarchy, but it's maybe a bit overkill for your situation. Said differently: You seem to want a principled way to make a typeclass for complex numbers. The standard typeclasses likeNumthat you are wanting to work with are very ad-hoc :-( - gsprFloatinganyway; complex numbers are mostly useful in a context of roots and/or exponentials (to describe oscillations). - leftaroundaboutRatio Integertoo. - gsprData.Complex.Complex Rational. hackage.haskell.org/package/cyclotomic has a proper implementation. - leftaroundabout