Implementing Gaussian integers in Haskell
This looks good. All necessary type signatures are there, no type is too strict nor too generic. The indentation style is familiar, and the braces on data Gaussian are easy to read, so no worries about that.

However, there are a few oddities. Let's face them.

Num's signum

There aren't any laws for Num in the Haskell report, however there are some expectations. The operations on (+) and (*) should implement a ring and that's certainly true here. However, Num's documentation indicates that the following should hold:

abs x * signum x = x -- (1)


Unfortunately, we cannot take the easy way and just use

signum x = x / abs x


since the result is unlikely to be in Gaussian's domain. As we cannot hold (1), we're free to do whatever we want, but it should be reasonable. How does it become reasonable? By documenting your decision:

signum = id -- &lt; your documentation here &gt;


Prefix vs. postfix documentation

That took me by surprise. Most of Haskell's documentation is placed before the documented item, not after. The same holds for most other documentation in other languages, where the documentation is placed before or in the function itself:

/** @brief Calculates the absolute value of a Gaussian integer.
 *  @param x is a Gaussian integer
 *  @returns x's absolute value
*/
int g_abs(gint x) {
    return x.r * x.r + x.i * x.i;
}


def g_abs(x):
    """Returns the absolute value of x"""
    return x.r * x.r + x.i * x.i


The usual Haddock documentation also placed the documentation before the item, although it's possible to use postfix.

You're welcome to stay in the postfix style, but you should indicate that your documentation refers to the preceding item, for example with Haddock's ^:

i :: Gaussian
i = 0 :+ 1
--^ The imaginary unit, equal to sqrt(-1).


That removes possible ambiguity.

two = 2 :: Integer and x ^ two

The line two = 2 :: Integer violates the DRY principle, thus any optimization or bugfix on x ^ two needs to get repeated throughout the program, which is error prone.

However, there is a greater issue. GHC rewrites x ^ 2 to x * x (see Note [Inlining (^) in base's documention). An explicit variable might hinder that process.

Instead, you should provide a square function or just immediately multiply a value with itself. Both variants will get rid of the warnings and additional bindings, for example:

--| The Num instance for Gaussian.
--  We use the euclidean norm as abs. norm(a + bi) = a^2 + b^2
instance Num Gaussian
  where
    ...
    abs (a :+ b) = (a * a + b * b) :+ 0
    signum = id -- chosen at random
    ...


By the way: if you chose square x = x ^ (2 :: Int) you won't need to repeat your documentation.

Precision

You always want to stay as precise as possible, unless you are aiming for speed. Therefore, you should try to stay in exact types till the very last moment in magnitude.

Instead of

magnitude :: Floating c =&gt; Gaussian -&gt; c
magnitude (a :+ b) = sqrt $ (square $ fromInteger a) + (square $ fromInteger b)


use

magnitude :: Floating c =&gt; Gaussian -&gt; c
magnitude (a :+ b) = sqrt $ fromInteger (square a + square b)


You could also reuse abs if you split it into two functions:

instance Num Gaussian where
    ...
    abs x = (absIntegral x :+ 0)
    ...

absIntegral :: Gausian -&gt; Integer
absIntegral (a :+ b) = square a + square b

magnitude :: Floating c =&gt; Gaussian -&gt; c
magnitude = sqrt . fromInteger . absIntegral