Modulo

Modulo is a curried constructor used to create a JS/JSON configuration object that represents a modulo operation.

const Modulo =
  (datatype = "Number") =>
  dividend =>
  divisor => ({
    tag: "Modulo",
    dividend,
    divisor,
    datatype,
  })
 
export default Modulo
 

The first parameter to Modulo determines the datatype of the return value of the modulo operation: Number (float) or Integer.

The second parameter is the dividend; the third is the divisor. Both are operations, which must eventually evaluate to values. The divisor will eventually be divided into the dividend to produce the modulus (result).

The dividend and divisor operations (multiply, subtract, etc.) may be nested to any depth, but the bottom (leaf) nodes must return values. Values are injected with injectors.

Because Modulo is curried, we can simplify our code by partial application, for example, const Mod = Modulo("Integer"). This returns a function that takes the dividend and divisor operations and returns a Modulo configuration for working with integers.

See below for an example.

The modulo function

We pass our configuration object to composeOperators, which composes the operations and returns a single function. This function takes an optional argument and returns the result of the calculation as a Right, e.g., { right: 42 }, or a Left with an array of Error objects, { left: [Error] }.

const modulo = operation => (arg? => Either<Array<Error>, result>)

composeOperators works by recursing down through the operation object, calling the correct operator function based on the tag (e.g., "Modulo"), and composing the functions returned. composeOperators then returns this composed function. See composeOperators for a more detailed explanation.

The injectors are not called until this composed calculate function is run. Hence, evaluation is lazy: the values are not injected until the last moment.

See the injectors for a complete list of how values may be injected. See the list of operators for the full range of available mathematical operations.

Example

We use composeOperators to create a calculate function, passing it our Modulo operation object. We call the calculate function and pass it an (optional) argument to run our operation(s) and calculate the modulus.

Here our dividend operation is a nested multiplication operation of three constants (using Constant). Our divisor is also an operation that returns the argument passed to the composed function (using FromArgument).

Try leaving one of the numbers undefined to see an Error returned. Also, play around with positive and negative dividends and divisors, then compare with Remainder.