# 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
}
);```

### `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 }),
}
);
// oval.center === Coordinates(150, 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)
),

Shape.Circle(
centre.translate(x, y, z),
)
})
};```

### `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."```

## Deno

This codebase uses the assertion library from Deno.