README
@visisoft/staticland v{{ config.meta.version }}
Operations (Mapping, Lensing, etc.) on Algebraic Data Types (ADT) (Either, Maybe, Promise, CancelableComputation) realised with free static functions.
The data-holding types are modelled with "simple" native JavaScript constructs as Array
, Promise
or Function
. Thus, the algebraic operations do not expect objects from ADT classes but work on those "simple" JavaScript types.
Using simple native types means that
- Conversion between the types is easy, but
- @visisoft/staticland practically gives up on type inspection and leaves that to the calling code. This is in line with the characteristics of JavaScript.
of |
map |
chain |
Consumption | |
---|---|---|---|---|
CancelableComputation | cc = (resolve, reject) => () => () |
new Promise(cc) |
||
Either | x => [,x] |
Array.prototype.map |
Array.prototype.flatMap |
xs => xs[1] |
Maybe | x => [x] |
Array.prototype.map |
Array.prototype.flatMap |
xs => xs[0] |
Promise | Promise.resolve |
Promise.then |
Promise.then |
Promise.then |
IO | x => x |
compose |
run(compose) |
call |
In a way @visisoft/staticland provides functions which operate on and access types you operate with anyway.
Homepage and Documentation
Hello @visisoft/staticland
Installation
When developing for Node.js
npm install @visisoft/staticland
When developing for the browser
npm install --no-optional @visisoft/staticland
Hello Earth
Greeting with a 0.5 sec 2-way delay.
Usage in an ES module
import {map as map_p, mapRej as mapRej_p, chain as chain_p} from '@visisoft/staticland/promise';
import {fromThrowable} from '@visisoft/staticland/either';
import {fromNilable, getOrElse} from '@visisoft/staticland/maybe';
import {curry, pipe} from 'ramda'; // or pipe from 'crocks' or any other composition function
const
// :: String -> {k: String} -> Maybe String
getProperty = R.curry((property, object) => fromNilable(object[property])),
// :: a -> Promise any a
delay = x => new Promise(resolve => setTimeout(resolve, 500, x)),
// :: any -> Either Error String
safeGreet = fromThrowable(x => "Hello " + x.toString() + "!"),
// :: any -> Promise (Maybe String) String
getAnswer = R.pipe(
delay, // Promise any any
map_p(safeGreet), // Promise any (Either Error String)
chain_p(delay), // Promise any (Either Error String)
chain_p(eitherToPromise), // Promise (any|Error) String
mapRej_p(getProperty('message')) // Promise (Maybe String) String
);
getAnswer("Earth")
.then(console.log, me => console.warn(getOrElse("unknown error", me)));
// -> "Hello Earth!"
getAnswer(null)
.then(console.log, me => console.warn(getOrElse("unknown error", me)));
// -> "Cannot read property 'toString' of null"
Usage in a CommonJS module
const
{chain: chain_p} = require('@visisoft/staticland/promise'),
delay = t => x => new Promise(resolve => setTimeout(resolve, t, x));
chain(delay(500), Promise.resolve("foo")).then(console.log);
Objective
Support programming in functional pipelines by exposing a familiar set of operations on asynchronous, optional and faulty data.
Design
Most functions comply with Static-Land`s algebraic laws. Where this is not possible (e.g. nesting of resolved Promises) a few reasonable paradigms have to be followed when using this library.
At the expense of complete algebraic lawfulness the data wrapping remains transparent and light-weight.
The functions are designed to support the usual functional programming style in JavaScript as it is the design philosophy for many libraries for example Ramda's:
- Emphasise a purer functional style. Immutability and side-effect free functions help to write simple yet elegant code.
- Automatic currying. This allows you to easily build up new functions from old ones simply by not supplying the final parameters.
- Parameter order supports convenient currying. The data to be operated on is generally supplied last, so that it's easy to create functional pipelines by composing functions.
Related Fantasy-Land Libraries
Ramda-Fantasy is very well documented, but sadly no longer maintained. Crocks is an exemplary implementation of common data types.
Dependencies
As FP utility library Ramda is used.
closed over
A closure is the combination of a function and the lexical environment within which that function was declared.