Different type restrictions for the same instance

I define my own data type with numeric numbers as an exercise for learning, and I ran into the problem of overloading absalong with other members Num. As far as I know, only one instance definition is allowed for each class, but if I could 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

Since none of the members except absrequires types Floating, and I do not want to limit them to types only Floating, but the function is absvery important, and I do not want to exclude it without need.
Is there a way I can have a function (+), (-)and (*)to work with all numeric types, while maintaining abs?

7.6.3.4. GHC, , (?) (, instance C [a] instance C [Int]), , (, instance C [a] instance Integral a => C [a]).

+4
1

, Prelude - . , (, @leftaroundabout, , Complex -, Floating).

:

  • Floating a Num (Complex a). , - shoehorning instance Num a => Num (Complex a) Num, abs.
  • . numeric-prelude. ( ):

    class (Field.C a) => Algebraic.C a where
      sqrt :: a -> a
    
    class (Ring.C a) => Field.C a where
      (/)           :: a -> a -> a
      recip         :: a -> a
      fromRational' :: Rational -> a
      (^-)          :: a -> Integer -> a
    
    class (Ring.C a) => Absolute.C a where
      abs    :: a -> a
      signum :: a -> a
    
    class (Additive.C a) => Ring.C a where
      (*)         :: a -> a -> a
      one         :: a
      fromInteger :: Integer -> a 
      (^)         :: a -> Integer -> a
    
    class Additive.C a where
      zero     :: a
      (+), (-) :: a -> a -> a
      negate   :: a -> a
    

    instance Additive.C a => Additive.C (Complex a), instance Ring.C a => Ring.C (Complex a) instance Algebraic.C a => Absolute.C (Complex a).

  • , . ( ), ( , ).

+4

Source: https://habr.com/ru/post/1668926/


All Articles