An open API service indexing awesome lists of open source software.

https://github.com/falinor/fp-ts-cheatsheet


https://github.com/falinor/fp-ts-cheatsheet

Last synced: 5 months ago
JSON representation

Awesome Lists containing this project

README

          

# fp-ts cheatsheet

This cheatsheet is intended for any reader to understand and remember fp-ts' most used features.

**Table of Contents**

- [Combining functions](#combining-functions)
- [Pipe](#pipe)
- [Flow](#flow)
- [Common constructors](#common-constructors)
- [From a nullable value](#from-a-nullable-value)
- [Using a predicate](#using-a-predicate)
- [Using a refinement](#using-a-refinement)
- [Either](#either)
- [Useful functions](#useful-functions)
- [Task](#task)
- [Useful functions](#useful-functions-1)
- [TaskEither](#taskeither)
- [Useful functions](#useful-functions-2)
- [Bind](#bind)
- [What does `W` in `chainW` mean?](#what-does-w-in-chainw-mean)
- [What does `K` in `fromNullableK` mean?](#what-does-k-in-fromnullablek-mean)
- [Glossary](#glossary)
- [Context value](#context-value)
- [Predicate](#predicate)
- [Refinement](#refinement)

## Combining functions

### Pipe
Definition: transform an expression in a data-first pipeline of functions.
```ts
import { pipe } from 'fp-ts/function'

const masters = ['Yoda', 'Vador', 'Luke']
pipe(
masters,
map(master => master.length),
filter(length => length > 4)
)
```

### Flow
Definition: like pipe but data-last.
```ts
import { flow } from 'fp-ts/function'

const value = ['Yoda', 'Vador', 'Luke']
flow(
map(master => master.length),
filter(length => length > 4),
)(masters)
```

## Common constructors

For all the monads that can fail below, these constructors exists

### From a nullable value
```ts
import { fromNullable } from 'fp-ts/Either'

// Without type signature
const mustExist = fromNullable(new CartMissingError())

// With explicit type signature
const mustExist: (cart: Cart | null) => Either = fromNullable(new CartMissingError())
```

### Using a [predicate](#predicate)
Test whether a predicate is true and return an error if not.
```ts
import { fromPredicate } from 'fp-ts/Either'

import { PropDifferentError } from '../errors'

const mustBeEqual: (obj: MyObject) => Either = fromPredicate(
obj => obj.prop === 'value',
obj => new PropDifferentError(obj.prop, 'value')
)
```

### Using a [refinement](#refinement)
Like a predicate but casts the given value into another type.
```ts
import { fromPredicate } from 'fp-ts/Either'

import { NotCartError } from '../errors'

const mustBeCart: (cartOrList: Cart | List) => Either = fromPredicate(
cartOrList => cartOrList.type === 'cart',
cartOrList => new NotCartError()
)
```

## Either
Definition: an error (left) or a value (right).
```ts
interface Left {
readonly _tag: 'Left'
readonly left: E
}

interface Right {
readonly _tag: 'Right'
readonly right: A
}

type Either = Left | Right
```

### Useful functions
Return error.
```ts
function left(e: E) => Either

left(new Error('error'))
```

Return success.
```ts
function right(a: A) => Either

right(42)
```

Map the inner type to another type.
```ts
function map
(f: (a: A) => B): (fa: Either) => Either

const either = right('string')
map(str => str.length)(either)
```

Chain with another Either.
```ts
function chain(f: (a: A) => Either): (ma: Either) => Either

pipe(
right(age),
chain(age => age < 18 ? left(new TooYoungError(age)) : right(age)
)

// With `fromPredicate`
const isOldEnough = fromPredicate(
age => age < 18,
age => new TooYoungError(age)
)

pipe(
right(age),
chain(isOldEnough)
)
```
You may use `Either.chainW` to [_widen_ the error type](#what-does-w-in-chainw-mean).

## Task
Definition: an asynchronous computation that yields a value and **never fails**.
```ts
interface Task
{
(): Promise

}
```

Task is often used when one destroys a TaskEither e.g.
```ts
await pipe(
useCase.execute(), // => TaskEither
fold(
error => Task.of(error),
value => Task.of(value)
)
)()
```
### Useful functions

delay(millis: number) : Creates a task that will complete after a time delay.
```ts
pipe(
T.chain(() => doSomething()),
T.chain(() => delay(1000)),
T.map(() => 'done after 1000ms')
)
```

## TaskEither
Definition: an asynchronous computation that **either yields a value** of type A or **fails, yielding an error** of type E
```ts
interface TaskEither extends Task> {}
```

### Useful functions

TODO

## Bind
Definition: bind allows to store a read-only context value in the composition pipeline, so that it can be reused later.

```ts
pipe(
bind('user', fromThunk(userRepository.save)),
// Here is the ContextValue
({ user }) => {
console.log(user)
}
)

// This is inferred by typescript
interface ContextValue {
readonly user: User
}
```
It forbids you to mutate the context value.

## What does `W` in `chainW` mean?
`W` means a function is able to aggregate errors into a union (for Either based data types) or environments into an intersection (for Reader based data types).
```ts
import * as E from 'fp-ts/Either'
import * as TE from 'fp-ts/TaskEither'
import { pipe } from 'fp-ts/function'

declare function parseString(s: string): E.Either
declare function fetchUser(id: number): TE.TaskEither

// This raises an error because: Type 'string' is not assignable to type 'Error'
const program_ = (s: string) => pipe(s, TE.fromEitherK(parseString), TE.chain(fetchUser))

// const program: (s: string) => TE.TaskEither
const program = (s: string) => pipe(s, TE.fromEitherK(parseString), TE.chainW(fetchUser))
```

## What does `K` in `fromNullableK` mean?
`K` in `fromNullableK` is used to do a `fromNullable` with a transformation (by a function) apply to the given agurments `
`
And then return either `NonNullable` or an error

```ts
export declare const fromNullableK: (
e: E
) =>
(f: (...a: A) => B | null | undefined) => (...a: A) => Either>
```

`K` means Kleisli. A Kleisli arrow is a function with the following signature
```ts
(a: A) => F
```
It's a sufix that we can find on other functions around the lib. ([more info on sufix](https://gcanti.github.io/fp-ts/guides/code-conventions.html))

## Glossary

### Context value
The value that transits throughout a pipe. See [bind](#bind).

### Predicate
A predicate is a function with the following signature:
```ts
(a: A) => boolean
```

### Refinement
A refinement is a special type of predicate that casts the given value in another type.
```ts
(a: A) => a is B
```