Skip to content

ModuloSemiring laws #61

@jonsterling

Description

@jonsterling

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:

  1. (a / 0) * 0 + mod a 0
  2. ==> Infinity * 0 + mod a 0
  3. ==> 0 + 0
  4. ==> 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.

@garyb @paf31

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions