algebra-ring.js
function algebraRing (identities, given) {
  // A ring is a group, with multiplication.

  const ring = group({
    identity: identities[0],
    contains: given.contains,
    equality: given.equality,
    compositionLaw: given.addition,
    inversion: given.negation
  })

  // operators

  function multiplication () {
    return [].slice.call(arguments).reduce(given.multiplication)
  }

  function inversion (a) {
    if (ring.equality(a, ring.zero)) {
      throw new TypeError(error.cannotDivideByZero)
    }

    return given.inversion(a)
  }

  function division (a) {
    const rest = [].slice.call(arguments, 1)

    return given.multiplication(a, rest.map(inversion).reduce(given.multiplication))
  }

  ring.multiplication = multiplication
  ring.inversion = inversion
  ring.division = division

  // Multiplicative identity.

  const one = identities[1]

  if (ring.notContains(one)) {
    throw new TypeError(error.doesNotContainIdentity)
  }

  // Check that one*one=one.
  if (ring.disequality(given.multiplication(one, one), one)) {
    throw new TypeError(error.identityIsNotNeutral)
  }

  if (ring.notContains(identities[1])) {
    throw new TypeError(error.doesNotContainIdentity)
  }

  ring.one = identities[1]

  return ring
}
function algebraRing (identities, given) {
  // A ring is a group, with multiplication.

  const ring = group({
    identity: identities[0],
    contains: given.contains,
    equality: given.equality,
    compositionLaw: given.addition,
    inversion: given.negation
  })

  // operators

  function multiplication () {
    return [].slice.call(arguments).reduce(given.multiplication)
  }

  function inversion (a) {
    if (ring.equality(a, ring.zero)) {
      throw new TypeError(error.cannotDivideByZero)
    }

    return given.inversion(a)
  }

  function division (a) {
    const rest = [].slice.call(arguments, 1)

    return given.multiplication(a, rest.map(inversion).reduce(given.multiplication))
  }

  ring.multiplication = multiplication
  ring.inversion = inversion
  ring.division = division

  // Multiplicative identity.

  const one = identities[1]

  if (ring.notContains(one)) {
    throw new TypeError(error.doesNotContainIdentity)
  }

  // Check that one*one=one.
  if (ring.disequality(given.multiplication(one, one), one)) {
    throw new TypeError(error.identityIsNotNeutral)
  }

  if (ring.notContains(identities[1])) {
    throw new TypeError(error.doesNotContainIdentity)
  }

  ring.one = identities[1]

  return ring
}
function algebraRing ( identities , given ) { // A ring is a group, with multiplication. const ring = group ( { identity : identities [ 0 ] , contains : given . contains , equality : given . equality , compositionLaw : given . addition , inversion : given . negation } ) // operators function multiplication ( ) { return [ ] . slice . call ( arguments ) . reduce ( given . multiplication ) } function inversion ( a ) { if ( ring . equality ( a , ring . zero ) ) { throw new TypeError ( error . cannotDivideByZero ) } return given . inversion ( a ) } function division ( a ) { const rest = [ ] . slice . call ( arguments , 1 ) return given . multiplication ( a , rest . map ( inversion ) . reduce ( given . multiplication ) ) } ring . multiplication = multiplication ring . inversion = inversion ring . division = division // Multiplicative identity. const one = identities [ 1 ] if ( ring . notContains ( one ) ) { throw new TypeError ( error . doesNotContainIdentity ) } // Check that one*one=one. if ( ring . disequality ( given . multiplication ( one , one ) , one ) ) { throw new TypeError ( error . identityIsNotNeutral ) } if ( ring . notContains ( identities [ 1 ] ) ) { throw new TypeError ( error . doesNotContainIdentity ) } ring . one = identities [ 1 ] return ring }
Define an algebra ring structure

@param {Array} identities
@param {*}     identities[0] a.k.a zero
@param {*}     identities[1] a.k.a uno
@param {Object}   given operator functions
@param {Function} given.contains
@param {Function} given.equality
@param {Function} given.addition
@param {Function} given.negation
@param {Function} given.multiplication
@param {Function} given.inversion

@returns {Object} ring
Define an algebra ring structure