Until today I had the assumption that fromInteger
in the Num
class was a ring homomorphism. I had assumed this because integer is is coterminal so every ring must have a unique homomorphism from integer, so it made sense that Num
, which is basically the ring class of the standard library, would include that homomorphism.
However today I was reading the laws for Num
and saw that fromInteger
is not required to be a homomorphism, but only required to preserve identities. So for example we can implement the Klein 4 group, and have fromInteger
map 1
to multiplicative identity and everything else to the addative identity, and the result is a legal Num
instance but not a homomorphism.
type Klein4
= ( Bool
, Bool
)
instance
(
)
=> Num Klein4
where
( a, b ) + ( c, d )
= ( a /= c
, b /= d
)
( a, b ) * ( c, d )
= ( a && b
, b && d
)
negate
= id
fromInteger x
= ( x == 1
, x == 1
)
This is a little surprising to me. So my question is why is this the case? Is the intention that fromInteger
is a ring homomorphism and I'm just being pedantic, or is there a good use case where you might want to define fromInteger
in a way that it is not a homomorphism (and still follows the Num
laws)?
Let A be a Noetherian commutative ring and Let A→B be a finite flat homomorphism of rings. We can thus form the so called "trace" TrB/A:B→A, which is a homomorphism of A - modules defined as follows: Every b∈B acts on B (when viewed as an A - module) by multiplication.
Claim: Let A be a commutative R-algebra (R-module that is a ring) and let a∈A. Then there is a unique algebra homomorphism φ:R[x]→A (R-linear map that is multiplicative) such that φ(1)=1, φ(x)=a.
Personally, I expect fromInteger
to be a ring homomorphism and would be very surprised and annoyed to find an instance that didn't have that property.
Of course, Float
and Double
have to be the exception to this, as to every good property. Suffice it to say that I am very surprised and annoyed by this:
> fromInteger (2^64) + fromInteger (-1) == (fromInteger (2^64-1) :: Double)
False
Most of the other proposed Num
properties are broken by Float
and Double
, too.
I don't know of any practical types that satisfy all the current Num
laws but not fromInteger x + fromInteger y == fromInteger (x+y)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With