Meaning and usage of complex number functor and monad?
Asked Answered
S

2

11

I was kinda surprised when I read the source code of instances of Applicative Complex and Monad Complex from GHC Data.Complex module:

-- | @since 4.9.0.0
instance Applicative Complex where
  pure a = a :+ a
  f :+ g <*> a :+ b = f a :+ g b
  liftA2 f (x :+ y) (a :+ b) = f x a :+ f y b

-- | @since 4.9.0.0
instance Monad Complex where
  a :+ b >>= f = realPart (f a) :+ imagPart (f b)

What the...? The Applicative Complex instance seems to treat complex numbers as just size-two arrays. And they both seem more like arrow operations. Is there any mathematical basis behind them? Either there is or not, what are they used for?

Stclair answered 8/11, 2017 at 13:32 Comment(3)
They are law-abiding instances, so there is no reason for them not to exist (this is the 'mathematical' basis)Raynaraynah
So there are no connections to complex analysis, and complex numbers are just size-two arrays here?Stclair
Complex numbers are, in some sense, just arrays of size 2. ℂ is isomorphic to ℝ².Elainaelaine
H
8

Edited to add note at bottom re: "linear" package.

The instances were added as per this Trac 10609 ticket initiated by a mailing list post where Fumiaki Kinoshita noted that there were some missing instances in the base libraries that seemed to be definable in only one way and proposed a patch to add them.

As far as I can see, there was no mathematical motivation for adding them, though there's at least one mathematically meaningful operation that can be expressed applicatively, namely scalar multiplication:

> pure (*) <*> pure 2 <*> (3 :+ 4)
6 :+ 8
>

In a follow-up to the above mailing list post, Edward Kmett noted that he was in favor because he'd had to add orphan instances for Complex to his linear package for years to make up for the missing instances.

It looks like he found them useful in defining an Additive instance for Complex thus essentially making a Complex a special case of a two dimensional vector.

Heartstricken answered 8/11, 2017 at 14:19 Comment(1)
Why use pure f <*> pure a <*> b instead of f a <$> b?Asdic
G
2

(Posting an answer since I don't have reputation to make comments, free feel to adjust.)

K. A. Buhr's answer addresses everything except the Monad instance, which is most strange. There is a mathematically obvious sense in which Complex does form a monad, prescribed by the equation (a + bi) + (c + di)i = (a - d) + (b + c)i. Of course, this requires that we work over a type class with notions of addition and subtraction.

(Contra user2407038, then: there is a good reason for this Monad instance to not exist even though it is "law-abiding": it is not the instance that implements expected behavior.)

By the way: this was briefly discussed in this blog post.

Goulette answered 31/8, 2022 at 21:32 Comment(1)
Agree that this is a good reason against the instance existing. I wish Haskellers stopped doing this kind of stuff.Saltire

© 2022 - 2024 — McMap. All rights reserved.