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)"
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)"
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
typeThe 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
typeThe 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
typeThe 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)
.
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";
This codebase uses the assertion library from Deno.
Author: sebastienfilion
Source Code: https://github.com/sebastienfilion/functional
#javascript #deno #nodejs #node