Alternatives To Fp Ts Cheatsheet
Project NameStarsDownloadsRepos Using ThisPackages Using ThisMost Recent CommitTotal ReleasesLatest ReleaseOpen IssuesLicenseLanguage
Language Ext5,355481542 days ago446June 29, 202251mitC#
C# functional language extensions - a base class library for functional programming
Pyrsistent1,7971,7223583 months ago71January 14, 202218mitPython
Persistent/Immutable/Functional data structures for Python
Robot1,72751418 days ago23May 28, 202229bsd-2-clauseJavaScript
🤖 A functional, immutable Finite State Machine library
List1,6385318a month ago33October 09, 201923mitTypeScript
🐆 An immutable list with unmatched performance and a comprehensive functional API.
Functionaljava1,48823057a year ago18February 11, 202228Java
Functional programming in Java
Monet.js1,44011189a year ago55November 28, 202125mitJavaScript
monet.js - Monadic types library for JavaScript
Omniscient1,19688104 years ago21October 19, 201711JavaScript
A library providing an abstraction for React components that allows for fast top-down rendering embracing immutable data for js
Partial.lenses79193463 years ago180November 06, 201820mitJavaScript
Partial lenses is a comprehensive, high-performance optics library for JavaScript
Bqn612
8 days ago1iscKakouneScript
An APL-like programming language. Self-hosted!
Functional Ruby551525 years ago15October 04, 20152otherRuby
A gem for adding functional programming tools to Ruby. Inspired by Erlang, Clojure, Haskell, and Functional Java.
Alternatives To Fp Ts Cheatsheet
Select To Compare


Alternative Project Comparisons
Readme

📝 fp-ts cheatsheet

More detailed explanations can be found in the Details document.

  1. Imports
  2. Pipe and Flow
  3. Option
  4. Either
  5. TaskEither
  6. Array and ReadonlyArray
  7. Do-notation

Imports

import { either, option } from 'fp-ts'; // import modules from root
import { flow, pipe } from 'fp-ts/functions'; // import functions from functions
import { Either } from 'fp-ts/Either'; // import types from their module

// rename common long module names
import { readerTaskEither as rte } from 'fp-ts';

Pipe and Flow

const value = 'value';

// Imperative style
const value1 = addSthg(value);
const value2 = doSthgElse(value1);
const finalValue = doFinalSthg(value2);
// Or maybe inline
const finalValue = doFinalSthg(doSthgElse(addSthg(value)));

// With pipe
const finalValue = pipe(value, addSthg, doSthgElse, doFinalSthg);

// With flow
const transformations = flow(addSthg, doSthgElse, doFinalSthg);
const finalValue = transformations(value);

Option

Create an Option<T>

// Build an Option
option.none;
option.some('value');

// Build from a value
option.fromNullable(null); // => option.none
option.fromNullable('value'); // => option.some('value')

// Build from a predicate
const isEven = number => number % 2 === 0;

option.fromPredicate(isEven)(3); // => option.none
option.fromPredicate(isEven)(4); // => option.some(4)

// Convert from another type (eg. Either)
const leftEither = either.left('whatever');
const rightEither = either.right('value');

option.fromEither(leftEither); // => option.none
option.fromEither(rightEither); // => option.some('value')

Extract inner value

const noneValue = option.none;
const someValue = option.of(42);

// Convert Option<T> to T | undefined
option.toUndefined(noneValue); // => undefined
option.toUndefined(someValue); // => 42

// Convert Option<T> to T | null
option.toNullable(noneValue); // => null
option.toNullable(someValue); // => 42

// Convert Option<T> with a default value
option.getOrElse(() => 0)(noneValue); // => 0
option.getOrElse(() => 0)(someValue); // => 42

// Convert Option<T> to T | U with a default value of type U
option.getOrElseW(() => 'default')(noneValue); // => 'default': number | string

// Apply a different function on None/Some(...)
const doubleOrZero = option.match(
  () => 0, // none case
  (n: number) => 2 * n // some case
);

doubleOrZero(noneValue); // => 0
doubleOrZero(someValue); // => 84

// Pro-tip: option.match is short for the following:
const doubleOfZeroBis = flow(
  option.map((n: number) => 2 * n), // some case
  option.getOrElse(() => 0) // none case
);

Either

Create an Either<E, A>

// Build an Either
const leftValue = either.left('value');
const rightValue = either.right('value');

// Build from a value
either.fromNullable('value was nullish')(null); // => either.left('value was nullish')
either.fromNullable('value was nullish')('value'); // => either.right('value')

// Build from a predicate
const isEven = (num: number) => num % 2 === 0;

const eitherBuilder = either.fromPredicate(
  isEven,
  number => `${number} is an odd number`
);

eitherBuilder(3); // => either.left('3 is an odd number')
eitherBuilder(4); // => either.right(4)

// Convert from another type (eg. Option)
const noneValue = option.none;
const someValue = option.some('value');

either.fromOption(() => 'value was nullish')(noneValue); // => either.left('value was nullish')
either.fromOption(() => 'value was nullish')(someValue); // => either.right('value')

Extract inner value

const leftValue = either.left("Division by Zero!");
const rightValue = either.right(10);

// Convert Either<E, A> to A with a default value
either.getOrElse(() => 0)(leftValue); // => 0
either.getOrElse(() => 0)(rightValue); // => 10

// Apply a different function on Left(...)/Right(...)
const doubleOrZero = either.match(
  (error: string) => {
    console.log(`The error was ${error}`);
    return 0;
  },
  (n: number) => 2 * n,
);

doubleOrZero(leftValue); // => 0 - also logs "The error was Division by Zero!"
doubleOrZero(rightValue); // => 20

// Pro-tip: either.match is short for the following:
const doubleOrZeroBis = flow(
  either.map((n: number) => 2 * n),
  either.getOrElse((error: string) => {
    console.log(`The error was ${error}`);
    return 0;
  });
);

TaskEither

Create a TaskEither<E, A>

// Build a TaskEither
const leftValue = taskEither.left('value');
const rightValue = taskEither.right('value');

// The taskEither module also provides similar builder functions
// to either, namely: `fromNullable`, `fromOption`, `fromPredicate`...

// Convert from Either
const eitherValue = either.right(42);

taskEither.fromEither(eitherValue); // => taskEither.right(42)

// Build from an async function
const asyncIsEven = async (n: number) => {
  if (!isEven(n)) {
    throw new Error(`${n} is odd`);
  }

  return n;
};

const buildTaskEither = (n: number) =>
  taskEither.tryCatch(
    () => asyncIsEven(n),
    (error: Error) => error.message
  );

buildTaskEither(3); // => taskEither.left('3 is odd')
buildTaskEither(4); // => taskEither.right(4)

Extract inner value

// Simple case: an infaillible Task
const someTask = task.of(42);

// Invoking a Task returns the underlying Promise
await someTask(); // => 42

// TaskEither
const someTaskEither = taskEither.right(42);
const eitherValue = await someTaskEither(); // => either.right(42)
either.getOrElse(() => 0)(eitherValue); // => 42

// Or more directly
const infaillibleTask = taskEither.getOrElse(() => 0)(someTaskEither); // => task.of(42)
await infaillibleTask(); // => 42

ReadonlyArray

Basic manipulation

const someArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

// filter and map
const result = pipe(
  someArray,
  readonlyArray.filter(isEven),
  readonlyArray.map(square)
); // => [0, 4, 16, 36, 64]

// or in one go with filterMap
const result = pipe(
  someArray,
  readonlyArray.filterMap(
    flow(option.fromPredicate(isEven), option.map(square))
  )
);

Sort elements with Ord

const strings = ['zyx', 'abc', 'klm'];

// basic sort
const sortedStrings = pipe(strings, readonlyArray.sort(string.Ord)); // => ['abc', 'klm', 'zyx']

// reverse sort
const reverseSortedStrings = pipe(
  strings,
  readonlyArray.sort(ord.reverse(string.Ord))
); // => ['zyx', 'klm', 'abc']

// sort Option
const optionalNumbers = [option.some(1337), option.none, option.some(42)];

const sortedNums = pipe(nums, readonlyArray.sort(option.getOrd(number.Ord))); // => [option.none, option.some(42), option.some(1337)]

// sort complex objects with different rules
type User = {
  name: string;
  age: Option<number>;
};

const byName = pipe(
  string.Ord,
  ord.contramap((user: User) => user.name)
);

const byAge = pipe(
  option.getOrd(number.Ord),
  ord.contramap((user: User) => user.age)
);

const sortUsers = readonlyArray.sortBy([byAge, byName]); // will sort an array of users by age first, then by name

Do-notation

import { readerTaskEither as rte } from 'fp-ts';
import { pipe } from 'fp-ts/function';
import { ReaderTaskEither } from 'fp-ts/ReaderTaskEither';

declare const foo: ReaderTaskEither<R1, E1, A1>;
declare const bar: ReaderTaskEither<R2, E2, A2>;
declare const baz: (props: {
  foo: A1;
  bar: A2;
}) => ReaderTaskEither<R3, E3, A3>;
declare const quux: (props: {
  foo: A1;
  bar: A2;
  baz: A3;
}) => ReaderTask<R4, A4>;
declare const transform: (props: { foo: A1; bar: A2; baz: A3 }) => B;

pipe(
  rte.Do,
  rte.apS('foo', foo),
  rte.apSW('bar', bar),
  rte.bindW('baz', baz),
  rte.chainFirstReaderTaskKW(quux),
  rte.map(transform)
);
// => ReaderTaskEither<
//      R1 & R2 & R3 & R4,
//      E1 | E2 | E3,
//      B,
//    >
Popular Functional Programming Projects
Popular Immutable Projects
Popular Software Development Categories
Related Searches

Get A Weekly Email With Trending Projects For These Categories
No Spam. Unsubscribe easily at any time.
Typescript
Functional Programming
Immutable
Monad