non/spire — pull request #304 by denisrosset (2014-08-14 12:50:09+00:00)
Title: Signed[A].abs is made optional, to be used when A is an additive group

Hi all,

some mathematical objects are signed (or have parity), without necessarily having an absolute value.

For example, permutations have either sign +1 or -1, but the absolute value cannot be computed. There are several options:

i) leave `Signed` as is, and have users implement `def abs(a: A) = sys.error("Not implemented")` for such objects,
ii) write in the type class `def abs(a: A)(implicit ev: this.type <:< AdditiveGroup[A])` which has the advantage of being "free" especially when inlined
iii) write `def abs(a: A)(implicit ev: AdditiveGroup[A])` which requires the side-effect instantiation of `AdditiveGroup[A]`
iv) create an additional `SignedAbs` typeclass

I tried to implement ii), but there is a conflict with `IsReal[A]` which does not inherit `AdditiveGroup[A]`. Having `IsReal` inherit `AdditiveGroup` causes implicit resolution to fail because of ambiguity when implicits `Field[A]` and `IsReal[A]` clash.

I dislike the solution iii) because `abs` can be called quite often in user code, on types like Double, etc..., where the actual computation is very fast and any overhead is painful.

The status quo is not good because `Signed` is probably going to be migrated to non/algebra at some stage, and it should not have this kind of idiosyncrasies.