Frontend monads with consistent and beginner-friendly naming conventions.

Monads are function composers. They let you compose functions together to control your program flow.

- Monads let you map a function to a value.
- Monads are only ever in one state at a time. Each of their methods returns either the same monad or a new one in a different state.

Monads are a specific combination of ideas that you probably already understand. Because of this it can be hard to understand the whole but easy to grasp the parts.

Some almost monad things to help you understand:

**Promises are almost monads**: They provide a consistent interface to structure the flow of async data**Promises are almost monads**: They can only ever be in one state at a time. Resolved, Rejected.**Arrays are almost monads**: They can always have a function mapped to their value, regardless of what they contain.**Array.map is almost monadic**: It provides a level of immutability by returning a new array with the values changed.

All monads have these three methods. Some languages have different names for them, but their idea remains the same.

- Unit
- flatMap
- map

Unit is the monad constructor. It takes a value and returns a new monad of that state. Because monads deal with program flow and most monads have sort of sub types that represent one or more the states. The Unit's purpose is to let you declare a single monad of a specific state. E.g.

Some/None Left/Right Fetching/Error/Success

```
function unitExample() {
return test ? Some(value) : None();
}
```

The above function is consistent because it always returns a monad. However if `test`

is true it will return a`Some`

monad containing a value, otherwise it will return a `None`

.

*9/10 times you'd use the specific unit constructor for the monad you want but each monad does have a .unit method*

The second core function of a monad is Flatmap. It's not however the flatter version of map, in fact flatMap provideds the basis for map. Flatmap says I'll pass the current value to your function, you return me another monad.

Other terms: bind, chain

*Fronads chooses flatMap/map because they pair nicely.*

Map builds off both unit and Flatmap, and is essentially `value => flatMap(Unit(value))`

.
Map is a convenient flatMap. It knows that you probably want the same monad again and so automatically creates the one you want. Letting you do things like:

`Some(person).map(person => person.age)`

The above statement will return a new some containing the persons age.

The Either monad describes situations that have two distinct states: Right and Left. Often used If the Either is Right map/Flatmap will be called and if the Either is Left leftMap/leftFlatMap will be called.

If Identity has 1 state, Maybe has 1.5, Either has 2.

Provide functions to map both sides of the Either

function biMap(leftFn: function, rightFn: function): Either

Change the Either to a Right or Left based on the result of a predicate

function filter(predicate: function): Either

If the Either is a right change to a Some if the Either is a Left drop the value and return a None

function toMaybe(): Maybe

Create a Try Either. `func`

is immediately exceuted,
if an error is thrown the Either will be Left(error) otherwise
the value of `func`

is passed to a Right.

function Try(func: function): Either

Identity is the vanilla ice cream of monads. Plain and simple, it is a function composer with only one state. Identity says: "I will always map your function to my value".

```
// Composition
foo(bar(value));
// Compose
Compose(foo, bar)(value);
// Identity
Identity(value)
.map(bar)
.map(value)
.value();
```

- Hocks
- repeated Composition.

```
import {Identity} from 'fronads';
const add = aa => bb => aa + bb;
Identity(5)
.map(add(2))
.map(add(-10))
.value();
// -3
// Hocking a React component.
Some(UserProfile)
.map(connect(({user}) => ({user}))
.value();
```

Identity class

Perform a flatMap on the current identity

function flatMap(fn: function): Some

Return the identity's value. If the value is null, return `defaultValue`

function value(defaultValue?: *): *

The maybe monad is a way to represent null values without being forced to check for their existence. Maybe is the identity monad but with an added condition. The maybe says "I will only ever call map/flatmap if I am a Some. "

```
Some(5).map(ii => ii * 2) // Some(10)
None().map(ii => ii * 2) // None()
```

Maybe lets you declaratively write what should happen to data, but only excecutes if that data exists.

Some(value) None() Perhaps(value) PerhapsIn(value, path)

####

Maybe class

Return the maybe's value if it is 'some' or else return `defaultValue`

function value(defaultValue?: *): *

Change the Maybe to a Some or None based on the result of a predicate

function filter(predicate: function): Maybe

Change the Maybe to an Either. If `Some`

the value is placed in `Right`

if `None`

the value of `leftValue`

is placed in a `Left`

.

function toEither(leftValue: *): Either

Creates a new Maybe as 'Some' value

function Some(): Maybe

var person = Some({ name: "Derek Tibbs", child: Some({ name: "Derek Tibbs Jr" }) });

Creates a new Maybe as 'None' value

function None()

var person = Some({ name: "Derek Tibbs", child: None() });

Create a new Maybe where the value is uncertain.

function Perhaps(value: any): Maybe

var person = Perhaps(possibleNullValue);

Create a new Maybe from a deep uncertain value.

function PerhapsIn(value: any, path: Array.<string>): Maybe

var person = PerhapsIn({foo: {bar: possibleNullValue}}, ['foo', 'bar']);

Sometimes the state of your app can be represented through more than two states. The StateMonadFactory lets you create a monad with an arbitary number of state.

Given an array of names it will returns an on object of custom Unit functions.

StateFunctor(['Empty', 'Fetching', 'Refetching', 'Error', 'Success']) // { // EmptyState: EmptyState, // FetchingState: FetchingState, // RefetchingState: RefetchingState, // ErrorState: ErrorState, // SuccessState: SuccessState // } StateFunctor(['New', 'Edit', 'View']) // { // NewState: NewState, // EditState: EditState, // ViewState: ViewState // }

Task lets you create a description of an action that is resolved via a callback. It is useful for asynchronous operations. It can be thought of as a stricter more monadic version of a promise.

Task class

Perform a flatMap on the current value of the previous resolved computation

function flatMap(fn: TaskFlatMapper): Task

Perform a flatMap on the current value of the previous rejected computation

function leftFlatMap(fn: TaskFlatMapper): Task

Perform a map on the current value of the previous resolved computation

function map(fn: TaskMapper): Task

Perform a map on the current value of the previous rejected computation

function leftMap(fn: TaskMapper): Task

Run the computation and return the state as either a rejected or resolved promise.

function toPromise(): Promise

Create a new Task from a function that returns a promise.

function TaskPromise(value: any): Task