npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

funcrithmetic

v0.0.3

Published

Monadic wrapper for doing arithmetic operations in JavaScript

Downloads

8

Readme

funcrithmetic

npm module Build Status Dependencies devDependencies

Monadic wrapper for doing arithmetic operations in JavaScript

Goal

The main goal of funcrithmetic is to facilitate writing conventional arithmetic equations in a more straightforward way:

const goldenSection = (Math.sqrt(5) + 1) / 2
// vs.
const goldenSection = FR.of(5)
  .sqr()
  .add(1)
  .div(2)
  .valueOf()
// => 1.618033988749895

The module aims to expose arithmetic operators in an easy-to-use fashion as well as acting as a Maybe Monad. If the term "Maybe Monad" throws you off, or the terms "Applicative" and "Functor" mean nothing to you, don't worry. You don't need to care all that much about these extra capabilities. The module can be used without ever touching this part of the API.

It is however worth noting that because funcrithmetic is a "Maybe Monad", it guards you against non-number values, including undefined and null (more on this later).

Usage

To use funcrithmetic, an "entry point" for the arithmetic equation is picked - in this case the 5 - and the subsequent operators are chained in the desired order. The more complicated the equation is, the more the simplicity of the chain notation becomes apparent:

const truncatedPentagon = Math.sqrt((5 - Math.sqrt(5)) / 2)
// vs.
const truncatedPentagon = FR.of(5)
  .sqrt()
  .subFrom(5)
  .div(2)
  .sqrt()
  .valueOf()
// => 1.1755705045849463

Notice the FR.of in the beginning of the expression? This is how values are "lifted" into the wrapper in order to get access to the arithmetic methods on it. Similarly the .valueOf() unwraps the value again:

const wrappedFive = FR.of(5)
// => FR(5)

const wrappedTwentyFive = wrappedFive.sqr()
// => FR(25)

const wrappedTwenty = wrappedTwentyFive.sub(5)
// => FR(20)

const twenty = wrappedTwenty.valueOf()
// => 20

That's basically it.

  • .of(x): lifts a value into the wrapper.
  • .valueOf(): unwraps the value again.

The exposed arithmetic methods on the wrapped value are:

  • .add(x): adds x to the value.
  • .dec(): decreases the value by 1.
  • .div(x): divides the value by x.
  • .inc(): increases the value by 1.
  • .exp(x): exponentiates the value by x.
  • .mul(x): multiplies the value by x.
  • .neg(): negates the value.
  • .sub(x): subtracts x from the value.
  • .subFrom(x): subtracts the value from x.
  • .sqr(): squares the value.
  • .sqrt(): calculates the square root of the value.

Guarding against non-numbers

In order to be able to chain methods as long as you want without worrying about e.g. undefined or NaN, funcrithmetic guards against any non-number values internally:

FR.of('foo').add(2).valueOf()
// => undefined

FR.of(2).add('foo').valueOf()
// => undefined

FR.of(2).div(0).valueOf()
// => undefined

FR.of(-4).sqrt().valueOf()
// => undefined

Note that funcrithmetic regards Infinity and NaN as non-numbers. This is why FR.of(2).div(0).valueOf() doesn't yield Infinity and FR.of(-4).sqrt().valueOf() doesn't yield NaN.

Advanced usage

Because funcrithmetic is monadic, some extra methods are exist on the wrapper:

  • .map(f): takes any function f and applies it to the value.
  • .chain(f): takes any function f that returns a funcrithmetic wrapper and applies it to the value.
  • .ap(fr): applies a wrapper to another wrapper that holds a function.

Using .map:

const res = FR.of(64).map(x => Math.sqrt(x) * 2 + 5).valueOf()
// => 21

Using .chain:

const res = FR.of(10).chain(x => FR.of(x * x)).valueOf()
// => 100

Using .ap:

const add = a => b => a + b

const res = FR.of(add)
  .ap(FR.of(3).sqr())
  .ap(FR.of(4).sqr())
  .sqrt()
  .valueOf()
// => 5

Note that the function has to be curried in order to apply the wrappers one by one.

Installation

The module is distributed via npm:

npm install funcrithmetic

And can be imported as a ES2015 module or CommonJS module depending on you setup:

import FR from 'funcrithmetic'

const FR = require('funcrithmetic')

Development

Run tests on watch mode:

npm run dev

Run tests and ensure proper code formatting:

npm test

Automatically format the source code including tests:

npm run prettier