-
Notifications
You must be signed in to change notification settings - Fork 92
Description
I'm opening this ticket following a discussion with @paf31 on IRC. Here's what we've got:
-- | The `ModuloSemiring` class is for types that support addition,
-- | multiplication, division, and modulo (division remainder) operations.
-- |
-- | Instances must satisfy the following law in addition to the `Semiring`
-- | laws:
-- |
-- | - Remainder: ``a / b * b + (a `mod` b) = a``
class (Semiring a) <= ModuloSemiring a where
div :: a -> a -> a
mod :: a -> a -> a
This "law", however, is not valid unless we intend for the integers to fail to model the ModuloSemiring
structure. In fact, the only instance of ModuloSemiring
that actually follows this law presently is Unit
. The problem is that nowhere has the behavior of division by zero been accounted for....
counterexample
Here's an example of where the law fails for Number
. Fix a : Number
, and let b
be 0
. Then, we have the following chain of equations:
(a / 0) * 0 + mod a 0
==> Infinity * 0 + mod a 0
==> 0 + 0
==> 0
Therefore, a
must be 0
for any a
, which is clearly false.
discussion
what should we do? Unless I've made a mistake, this law is definitely wrong / not the intended definition of a ModuloSemiring
. Can we fix it though? One option would be to say that it must only hold for non-zero b
, but is that something we want to say in the type class itself? I'm curious what people think.