functools-ts
Motivation
I wrote this library to provide basics construction for writing code in functional style in Typescript.
This library doesn't intend to replace other library like lodash but a separate toolbox which you can use with.
Samples
Using pipe
Allow to pipe multiple operation on data
import { pipe, Right, Either } from "functools-ts"
pipe(
Right(42),
a => Either.map(a, x => x + 2),
a => Either.map(a, x => x + 4)
)
Compose
import { compose } from "functools-ts"
const f = compose(
(a: List<number>) => a.map(x => x * 2),
a => a.reduce((acc, num) => acc + num, 0)
)
f([1, 2, 3, 4])
Option
import { Option } from "functools-ts"
Option.map(null, n => n + 1)
Option.map(5, n => n + 1)
Option.sequence([1, 2, 3, null, 4])
Option.sequence([1, 2, 3, 4])
Remote data
An useful data structure to represent data that need to be fetch
Here the definition
type RemoteData = Unloaded | Pending | Failed<E> | Loaded<A>
I provide basic pattern matching on it like
import {Loaded, RemoteData} from "functools-ts"
const rd = Loaded(42)
RemoteData.match(rd, {
Loaded: x => `Loaded(${x})`,
Pending: () => "Pending",
Failed: error => `Failed(${error.toString()})`,
Unloaded: () => "Unloaded"
})
Form field
Data structure to represent data with validation
type FormField<E, A> = Valid<A> | Invalid<E, A>
import { FormField, Validation } from "functools-ts"
const field: FormField<string, number> = Valid(42)
FormField.match(field, {
Valid: x => console.log(x),
Invalid (x, errors) => console.log(errors)
})
const validateNumber = Validation.combine<string, number>(
x => x > 5 ? Valid(x) : Invalid(x, ["must be greater than 5"]),
x => x % 2 === 0 ? Valid(x) : Invalid(x, ["must be divisible by 2"])
)
validateNumber(5)
validateNumber(3)
validateNumber(6)
View (experimental)
Allow to view a range of the array
const v = ListView(0, 2, [1, 2, 3, 4, 5])
v.at(0)
v.foldLeft((acc, item) => acc + item, 0)
Async pipe
Write pipe allowing asynchronous function
const f = asyncPipe(
(x: number) => x + 42,
x => new Promise<number>(resolve => resolve(x)),
x => x + 4,
x => x + 4
)
f(4)
f(4).then(console.log)
with async group (parallel operations)
const f = asyncPipe(
asyncGroup((x: List<number>) => x.join(","), x => x.slice(2)),
asyncGroup(
([a, _]) => a.repeat(2),
([_, b]) => b.reduce((acc, n) => acc + n, 0)
),
([a, b]) => a + b
)
f([1, 2, 3, 4]).then(console.log)