While digging through Haskell’s `base`

libaries the other
day, I came across these surprising instances for
`Data.Complex`

, which seems intended to be a nice way to work
with complex numbers:

```
instance Applicative Complex
instance Monad Complex
```

It’s strange to see monads and applicatives for this kind of thing in
the first place (is a tuple `Num n => (n, n)`

a monad?).
However, i found it especially interesting how these specific instances
also lead to some pretty weird numeric behavior, if you’re expecting
`Complex`

to act anything like complex numbers in math.

First of all, `pure`

puts its argument in both the real
and imaginary part. So \(\mathrm{pure}\:1\) becomes \(1 + i\)

```
$ pure 1 :: Complex Double
1.0 :+ 1.0
```

This is because `pure`

just pairs its argument with
itself: `pure a = a :+ a`

. Because `Complex`

was
made so general, it doesn’t have access to a notion of “zero”, which
you’d need if you wanted to make this act more like
`pure a = a :+ 0`

.

The bind operation has more going on, so has more opportunity to seem bizarre from a math standpoint. If you try to add a “plain” number to a complex, you get oddities like this:

```
$ 1 :+ 2 >>= (+1)
2.0 :+ 0.0
```

And binding to a function of a complex does this piecewise thing (whereas \((2+3i)(4+5i)\) in math would be \(-7+22i\)).

```
$ 2 :+ 3 >>= (*(4 :+ 5))
8.0 :+ 15.0
```

Here’s the implementation that makes this behavior happen. It’s applying the bound function to both sides, but then a possible “combining step” is cut in favor of just taking the real part of the real part, and the imaginary part of the imaginary part.

```
instance Monad Complex where
a :+ b >>= f = realPart (f a) :+ imagPart (f b)
```

This seems like a case of being a little too parametric for your own
good. (It’s also a case of seeing a monad where a monad may not really
be the best model.) So, these instances on `Complex`

act more
like they’re for a general “pairing” than they are for complex
numbers.