Functional Programming Type Signature for JavaScript that is compatible

Functional

Type factory

The Type factory can be used to build complex data structure.

import { factorizeType } from "https://deno.land/x/functional/SumType.js"

const Coordinates = factorizeType("Coordinates", [ "x", "y" ]);
const vector = Coordinates(150, 200);
// vector.x === 150
// vector.y === 200

Type.from

from :: Type ~> Object -> t

Create an instance of Type using an object representation.

const vector = Coordinates.from({ x: 150, y: 200 });
// vector.x === 150
// vector.y === 200

Type.is

is :: Type ~> Type t -> Boolean

Assert that an instance is of the same Type.

Coordinates.is(vector);
// true

Type.toString

toString :: Type ~> () -> String

Serialize the Type Representation into a string.

Coordinates.toString();
// "Coordinates"

Type(a).toString

toString :: Type t => t ~> () -> String

Serialize the instance into a string.

vector.toString();
// "Coordinates(150, 200)"

Type Sum factory

import { factorizeSumType } from "https://deno.land/x/functional/SumType.js"

const Shape = factorizeSumType(
  "Shape",
  {
    // Square :: (Coord, Coord) -> Shape
    Square: [ "topLeft", "bottomRight" ],
    // Circle :: (Coord, Number) -> Shape
    Circle: [ "center", "radius" ]
  }
);

SumType.from

from :: SumType ~> Object -> t

Create an instance of Type using an object representation.

const oval = Shape.Circle.from(
  {
    center: Coordinates.from({ x: 150, y: 200 }),
    radius: 200
  }
);
// oval.center === Coordinates(150, 200)
// oval.radius === 200

SumType.is

is :: SumType ~> SumType t -> Boolean

Assert that an instance is of the same Sum Type.

Shape.Circle.is(oval);
// true

SumType.fold

Shape.prototype.translate =
  function (x, y, z) {
    return this.fold({
      Square: (topleft, bottomright) =>
        Shape.Square(
          topLeft.translate(x, y, z),
          bottomRight.translate(x, y, z)
        ),

      Circle: (centre, radius) =>
        Shape.Circle(
          centre.translate(x, y, z),
          radius
        )
    })
  };

SumType(a).toString

toString :: SumType t => t ~> () -> String

Serialize the instance into a string.

oval.toString();
// "Shape.Circle(Coordinates(150, 200), 200)"

Example of writing a binary tree with Sum Types

import { factorizeSumType } from "https://deno.land/x/functional/SumType.js"

const BinaryTree = factorizeSumType('BinaryTree', {
  Node: ['left', 'x', 'right'],
  Leaf: []
});

BinaryTree.prototype.reduce = function (f, accumulator) {

  return this.fold(
    {
      Node: (l, x, r) => {
        const left = l.reduce(f, accumulator);
        const leftAndMiddle = f(left, x);

        return r.reduce(f, leftAndMiddle);
      },
      Leaf: () => accumulator
    }
  );
};

const tree =
  BinaryTree.Node(
    BinaryTree.Node(
      BinaryTree.Leaf,
      1,
      BinaryTree.Node(
        BinaryTree.Leaf,
        2,
        BinaryTree.Leaf
      )
    ),
    3,
    BinaryTree.Node(
      BinaryTree.Node(
        BinaryTree.Leaf,
        4,
        BinaryTree.Leaf
      ),
      5,
      BinaryTree.Leaf
    )
  );

// tree.reduce((x, y) => x + y, 0) === 15

Maybe type

The Maybe type represents potentially Just a value or Nothing.

import Maybe from "https://deno.land/x/functional/Maybe.js"

const container = Maybe.Just(42);

const serialize = (container) =>
  container.fold({
    Nothing: () => "There is no value.",
    Just: value => `The value is ${value}.`
  });

// serialize(container) === "The value is 42."

This implementation of Maybe is a valid [Filterable](https://github.com/fantasyland/fantasy-land#filterable)[Functor](https://github.com/fantasyland/fantasy-land#functor)[Applicative](https://github.com/fantasyland/fantasy-land#applicative)[Alternative](https://github.com/fantasyland/fantasy-land#alternative)[Traversable](https://github.com/fantasyland/fantasy-land#traversable) and [Monad](https://github.com/fantasyland/fantasy-land#monad).

Either type

The Either type represents the possibility of two values; either an a or a b.

import Either from "https://deno.land/x/functional/Either.js"

const container = Either.Right(42);

const serialize = (container) =>
  container.fold({
    Left: value => `An error occured: ${value}.`,
    Right: value => `The value is ${value}.`
  });

// serialize(container) === "The value is 42."

This implementation of Maybe is a valid [Functor](https://github.com/fantasyland/fantasy-land#functor)[Applicative](https://github.com/fantasyland/fantasy-land#applicative)[Alternative](https://github.com/fantasyland/fantasy-land#alternative) and [Monad](https://github.com/fantasyland/fantasy-land#monad).

IO type

The IO type represents a function that access IO. It will be lazily executed when the #run method is called.

import IO from "https://deno.land/x/functional/IO.js"

// Eventually 42
const container = IO(_ => Promise.resolve(42));

const multiply = container.map(promise => promise.then(x => x * x));
const add = container.map(promise => promise.then(x => x + x));

// multiply === IO(Function)
// add === IO(Function)

const multiplyThenAdd = multiply.map(promise => promise.then(x => x + x));

// multiply.run() === Promise(1764)
// add.run() === Promise(84)
// multiplyThenAdd.run() === Promise(3528)

This implementation of IO is a valid [Functor](https://github.com/fantasyland/fantasy-land#functor)[Applicative](https://github.com/fantasyland/fantasy-land#applicative) and [Monad](https://github.com/fantasyland/fantasy-land#monad).

TypeScript

I will try to publish TypeScript type hint files for those who needs it.

So far, I’ve only implemented the Type factory functions.

// @deno-types="https://deno.land/x/functional/SumType.d.ts"
import { factorizeType, factorizeSumType } from "https://deno.land/x/functional/SumType.js";

Deno

This codebase uses the assertion library from Deno.

Download Details:

Author: sebastienfilion

Source Code: https://github.com/sebastienfilion/functional

#javascript #deno #nodejs #node

Functional Programming Type Signature for JavaScript that is compatible
2.50 GEEK