Skip to content

Instantly share code, notes, and snippets.

@lgastako
Last active July 2, 2026 10:17
Show Gist options
  • Select an option

  • Save lgastako/f8fc118711007c25d8b17656d86182a6 to your computer and use it in GitHub Desktop.

Select an option

Save lgastako/f8fc118711007c25d8b17656d86182a6 to your computer and use it in GitHub Desktop.
{-# OPTIONS_GHC -Wno-type-defaults #-}
module Complex
( Complex(..)
, Polar(..)
, Rectangular(..)
) where
newtype Polar = Polar (Double, Double)
newtype Rectangular = Rectangular (Double, Double)
class Complex a where
realPart :: a -> Double
imaginaryPart :: a -> Double
magnitude :: a -> Double
angle :: a -> Double
add :: a -> a -> a
multiply :: a -> a -> a
toPolar :: a -> Polar
toPolar z = Polar
( magnitude z
, angle z
)
toRectangular :: a -> Rectangular
toRectangular z = Rectangular
( realPart z
, imaginaryPart z
)
instance Complex Rectangular where
realPart (Rectangular (r, _)) = r
imaginaryPart (Rectangular (_, i)) = i
magnitude (Rectangular (r, i)) = sqrt (r^2 + i^2)
angle (Rectangular (r, i)) = atan2 i r
toRectangular = id
add ra rb = Rectangular
( realPart ra + realPart rb
, imaginaryPart ra + imaginaryPart rb
)
multiply a b = Rectangular
( realPart a * realPart b - imaginaryPart a * imaginaryPart b
, realPart a * imaginaryPart b + imaginaryPart a * realPart b
)
instance Complex Polar where
realPart (Polar (r, a)) = r * cos a
imaginaryPart (Polar (r, a)) = r * sin a
magnitude (Polar (r, _)) = r
angle (Polar (_, a)) = a
toPolar = id
add a b = toPolar $ add (toRectangular a) (toRectangular b)
multiply a b = Polar
( magnitude a * magnitude b
, angle a + angle b
)
instance Num Polar where
(+) = add
(*) = multiply
negate (Polar (r, a)) = Polar (r, a + pi)
abs (Polar (r, _)) = Polar (r, 0)
signum (Polar (r, a))
| r == 0 = Polar (0, 0)
| otherwise = Polar (1, a)
fromInteger n
| n >= 0 = Polar (fromInteger n, 0)
| otherwise = Polar (fromInteger (abs n), pi)
instance Num Rectangular where
(+) = add
(*) = multiply
negate (Rectangular (x, y)) = Rectangular (-x, -y)
abs z = Rectangular (magnitude z, 0)
signum z
| magnitude z == 0 = Rectangular (0, 0)
| otherwise =
let m = magnitude z
in Rectangular
( realPart z / m
, imaginaryPart z / m
)
fromInteger n = Rectangular (fromInteger n, 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment