npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

monad-ts

v0.3.17

Published

Monad-ts is a small library implements some of key monads and way to chain them in a pipe (flow) in JavaScript and TypeScript. Angular 2+ compatible.

Downloads

102

Readme

Build Status npm Gemnasium Hex.pm

Monad-ts

Monad-ts is a small library implements some of key monads and way to chain them in a flow (pipe) in JavaScript and Typescript. Angular 2+ compatible

Example app 1.

Example app 2 with monad transformers.

Content

Introduction

All monads

Additional tools (class and functions)

Examples

Installation

In library used ES5 (Array.map, Array.reduce, Array.some, Array.isArray, Object.getOwnPropertyNames), ES6 (Map, Array.from, Object.assign, Object.keys, Object.is) methods. It's strongly recommended to always use ES5-shim and ES6-shim or alternatives.

npm install monad-ts

or

 yarn add monad-ts

Tests

Clone the repo, npm install or yarn and run tests.

npm run test

or

 yarn test

Intro

One of the main ideas of functional programming is to use pure functions as much as possible. But pure functions don't do any kind of side-effects. At the same time the majority of programs should operate with side-effects in process. Monads allow us to do all the side-effecting computations using pure functions effectively.

NB This monads implementation aren't exact copy of Haskell monads. My goal was to reach results comparable with the using of like monads from Haskell in JS.

NB For catching Errors, produced within monads you should use monad ErrorM.

Setup

1. SystemJS Configure systemjs.config.js to register the module.

SystemJS.config({
	map:{
		...
		'monad-ts': 'node_modules/monad-ts/lib/monad_ts.umd.js'
		...
	}
})

2. WebPack No special configuration.

Example:

import {Flow, List} from "monad-ts"

const list = new List();
const e: number = 50;
let r : number;
let t : number[];
console.log(t); // undefined
console.log(r); // undefined
const z = new Flow(5)
    .bind((v: number): any => v+1)
    .let((v: number): any => new Flow(v).bind((v: number) => r = v+e))
    .bind((v: number): any => cast(list.bind((v: number) => [v-1, v, v+1], [-v, v ]), 1))
    .let((v: number)=> new Flow(v).bind((v: number[]) => t = v, cast(list.bind((v: number)=>[v, -v], [v]), 2)))
    .subscribe();
console.log(r); // 56
console.log(t); // [ -7, 7, -6, 6, -5, 5, 5, -5, 6, -6, 7, -7 ]
console.log(z); // [ -7, -6, -5, 5, 6, 7 ]

UP

Monads

Either

It represents computation with two possibilities, right and left. Attached by bind method dispatcher function decided which of them apply to underlying value.

Example:

const uVal = 10;                                     // underlying value
const right = (x: number) => x+1;                    // if cond(v) return true, than executed
const left = (y: string) => y + ' - isn\'t string';  // if cond(v) return false, than executed
const cond = (v:any) => typeof v === 'string';       // dispatcher function - cond(v)
const e = new Either(right, left).bind(cond , uVal); // '10 - isn't string'

ErrorM

It similar to the Identity but it can also represent the error. Error monad returns value transformed by given function. If Error monad gets Error in given values it produce Error. If after application of given transformation function monad get Error monad produce Error.

Examples:

const e = new ErrorM();
e.bind((v: number) => e.bind((v1: number)=>v+v1, 1), 1/0); // Error

Identity

It returns underlying value transformed by given function. We can add underlying value in constructor or in bind method.

Examples:

const i = new Identity(3);    // Identity({v: 3})
i.bind((v:number) => v);      // 3
const i = new Identity();
i.bind((v:number) => v, 3); // 3

Maybe

It similar to the Identity but it can also represent the absence of any value. Monad Maybe returns value transformed by given function. If Maybe monad gets null or undefined in given values it produce null. If after application of given transformation function monad get null or undefined monad produce null.

Examples:

const maybe = new Maybe();
type G = { url: string; getUrl: () => any; };
const z: G = {
    url: 'http://...',
    getUrl: function (){
        return this.url;
    }
};
maybe.bind(r => r.getUrl(), z); // http://...

List

The List monad represents a computed list of values. It takes in an input value of type A, and produce a bunch of output values of type B, collected in one container (the array).

It get array and return array, to cast array dimension according to entered array we can use function cast;

Examples:

const list = new List();
const x = [10, 2];                                                                         // Entered array
z = cast(list.bind((v: number) =>list.bind((v: number) => [-v, v], [v-1, v, v+1]), x), 2); // [ -9, 9, -10, 10, -11, 11, -1, 1, -2, 2,
-3, 3 ]

State

The State monad interact with local and global state variables to transform them. After initializing an instance of State monad we can not add new keys to the state object. It take object.

The instance of the State monad can be initialized in two ways.

  1. While the instance create - in constructor (Ex.1).

  2. After instance created - use bind() method (Ex.2). The function x => x in st.bind(x => x, initState); is for backward compatibility with previous versions, it's unused in the method. Delayed initialization can be useful in some cases.

Example 1:

type R = { data: number; children: any[]; arr: number[]; };
    const initState: R = {
        data: 1,
        children: [{
            data: 2,
            parent: 'null'
        }],
        arr:[1,2,3]
    };
    const st = new State(initState);
    console.log(st.get()); // return initState object
    st.put((v: R) => {
                v.data = 10;
                v.arr = list.bind((x:number) => x+f, v.arr);
                return v;
            });
    console.log(st.get()); // { data: 10, children: [ Object({ data: 2, parent: 'null' }) ], arr: [ 2.25, 3.25, 4.25 ] }

Example 2:

type R = { data: number; children: any[]; arr: number[]; };
    const initState: R = {
        data: 1,
        children: [{
            data: 2,
            parent: null
        }],
        arr:[1,2,3]
    };
    const st = new State();
    console.log(st.get()); // State -> undefined
    st.bind(x => x, initState);
    st.put((v: R) => {
                v.data = 10;
                v.arr = list.bind((x:number) => x+f, v.arr);
                return v;
            });
    console.log(st.get()); // State -> { data: 10, children: [ Object({ data: 2, parent: null }) ], arr: [ 2.25, 3.25, 4.25 ] }

UP

Additional utilities (class and functions)

AsyncFlow

For composing monads in an async flow (pipe), based on Promise. Class instance creation new AsyncFlow(initV, encapsulate?). Initial value (initV) encapsulated in the class instance by default. If set encapsulate = false, then initial value wouldn't be encapsulated and we will be able to change inner state of the class instance by changing initV.

NB Initial value should be statically analyzable.

new AsyncFlow(5)
  .bind((v) => v)
  .then((v) => v)
  .then((v) => cast(list.bind((v:number) => [v-1, v, v+1], [v]), 1))
  .then(v=> wait(v,100))
  .then((v)=> {
      console.log(v);                 // v = [4,5,6], emitted after 100 ms
  });

Flow

For composing monads in a flow (pipe). Class instance creation is identical to AsyncFlow.

const e: number = 50;
let r : number;
let t : number[];
const z = new Flow(5)
  .bind((v: number): any => v+1)
  .let((v: number): any => new Flow(v).bind((v: number) => r = v+e))
  .bind((v: number): any => cast(list.bind((v: number) => [v-1, v, v+1], [-v, v ]), 1))
  .let((v: number)=> new Flow(v).bind((v: number[]) => t = v, cast(list.bind((v: number)=>[v, -v], [v]), 2)))
  .subscribe();
console.log(r); // 56
console.log(t); // [ -7, 7, -6, 6, -5, 5, 5, -5, 6, -6, 7, -7 ]
console.log(z); // [ -7, -6, -5, 5, 6, 7 ]

cast

Function to decreasing the dimension of an array by factor n. It takes array and factor.

console.log(cast([10, [11], [12]], 0));           // [10, [11], [12]]
console.log(cast([10, [[11, [2]], 3], [12]], 2)); // [ 10, 11, [ 2 ], 3, 12 ]

clone

Function to clone objects (including Map). It takes objects, arrays and primitives.

const x = {x:1};
const z = clone(x);
z.x = 10;
console.log(z); // {x:10}
console.log(x); // {x:1}

debounceTime

Execute a function given a delay time. debounceTime(func, d, i?), func - invoked function, d - a delay time, i - delay before func execution, by default is absent.

equality

It checks equality of given arguments, arguments must be statically analyzable, therefore there are some constraints, look at examples to find them.

// true
equality(
  {x1: 0, x: [1, {c: [22, {j:21, g: 'ert'}, 23]}, NaN, Infinity, null, undefined], t: [null, 0]},
  {x1: 0, x: [1, {c: [22, {j:21, g: 'ert'}, 23]}, NaN, Infinity, null, undefined], t: [null, 0]}
)

hash

It calculates a hash (32 bit).

let g = hash('test "#^test "#^test "#^testRrr G!@#$%^&*()__+<>?ZXCV":A'); // g = 2692353561

wait

Function to convert timeout in a Promise, resolved when specified amount of time passes. It take value (v) end emit Promise after t timeout with value (v). wait(v, t) It produce a promise rejection handler on an Error occur.

const s = wait(1, 300).then((v: number)=>{
            console.log(v);                 // v = 1, emitted after 300 ms
        })

UP

License

Monad_ts is copyright (c) 2017 - present Alex Tranchenko [email protected] .

Monad_ts is free software, licensed under the Apache License, Version 2.0. See the file LICENSE.md in this distribution for more details.