Skip to content

A1c0/sanctuary-lourdes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

65 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sanctuary Lourdes

An utils library created by and for Sanctuary

Get started

Installation

npm i sanctuary-lourdes
# OR
yarn add sanctuary-lourdes

Usage

create instance of Sanctuary Lourdes near your instance of Sanctuary

import sanctuary from 'sanctuary';
import {create} from 'sanctuary-lourdes';

const CHECK_TYPES_SANCTUARY = process.env.CHECK_TYPES_SANCTUARY === 'true';

const S = sanctuary.create ({
  checkTypes: CHECK_TYPES_SANCTUARY,
  env: sanctuary.env
});

const Sl = create({checkTypes: CHECK_TYPES_SANCTUARY});

API

Array

Get the N th elements of array

> Sl.nth (0) ([])
Nothing

> Sl.nth (1) ([1, 2, 3])
Just (2)

> Sl.nth (7) ([1, 2, 3])
Nothing

Get the first index of an array which corresponding to an item

> Sl.indexOf ('red') (['red', 'green', 'blue'])
Just (0)

> Sl.indexOf ('yellow') (['red', 'green', 'blue'])
Nothing

> Sl.indexOf ({name: "white", hex: "#fff"})
.            ([{name: "white", hex: "#fff"}, {name: "black", hex: "#000"}])
Just (0)

Split an array on sub-array of size N

> Sl.splitEach (3) ([1, 2, 3, 4, 5, 6, 7, 8, 9])
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

> Sl.splitEach (2) ([1, 2, 3, 4, 5, 6, 7])
[[1, 2], [3, 4], [5, 6], [7]]

Separate each item by an item.

> Sl.intersperse ("b") (["a", "c"])
["a", "b", "c"]

> Sl.intersperse ("b") (["a"])
["a"]

> Sl.intersperse ("b") ([])
[]

Regex

Get the first group match in a string

> const extractStringExample = Sl.extractString (/hello ([a-z]*)!/);

> extractStringExample ('hello john!')
Just ("john")

> extractStringExample ('hello bob!')
Just ("bob")

> extractStringExample ('hello 123!')
Nothing

> extractStringExample ('hi john!')
Nothing

Replace a substring with a RegExp

> Sl.replace (/bob/) ('john') ('hello bob')
"hello john"

> Sl.replace (/a/gi) ('o') ('Aaaaahhhh')
"ooooohhhh"

Logic

Return true if all predicates return true, else return false

> const isEvenNumber = x => x%2 === 0;
> const isPositiveNumber  = x => x > 0;
> const isPositiveEvenNumber = Sl.allPass ([isEvenNumber, isPositiveNumber]);

> isPositiveEvenNumber (0)
false

> isPositiveEvenNumber (1)
false

> isPositiveEvenNumber (-2)
false

> isPositiveEvenNumber (2)
true

Return true if one of predicates return true, else return false

> const isSix = x => x === 6;
> const isNegative  = x => x < 0;
> const isNegativeOrSix = Sl.anyPass ([isNegative, isSix]);

> isNegativeOrSix (0)
false

> isNegativeOrSix (1)
false

> isNegativeOrSix (-2)
true

> isNegativeOrSix (6)
true

Apply transformer predicate return true anc return a Right value If any predicate return true, it will return initial value in Left Value

> const condExample = Sl.cond ([
.   S.Pair (S.test (/^[a-zA-Z]+$/)) (S.toUpper),
.   S.Pair (S.test (/[a-zA-Z]+/)) (S.toLower),
. ]);

> condExample ('hello')
Right ("HELLO")

> condExample ('HELLO!')
Right ("hello!")

> condExample ('123!')
Left ("123!")

Lens

Use implementation created by David Chambers

Allow to get a value by a Lens

> const email = Sl.lens (user => user.email) (email => user => ({...user, email}));
> const user = {id: 1, email: '[email protected]'};

> Sl.view (email) (user)
dc@davidchambers.me

Allow to set a value by a Lens

> const email = Sl.lens (user => user.email) (email => user => ({...user, email}));
> const user = {id: 1, email: '[email protected]'};

> Sl.over (email) (S.toUpper) (user)
{id: 1, email: '[email protected]'}

Create a Lens for an object property

> const user = {id: 1, email: '[email protected]'};

> Sl.view (Sl.lensProp('email')) (user)
'[email protected]'

> Sl.over (Sl.lensProp('email')) (S.toUpper) (user)
{id: 1, email: '[email protected]'}

Create a Lens for an object property path

> const example = {a: {b: {c: 1}}};

> Sl.view (Sl.lensProps (['a', 'b', 'c']))
.         (example)
1

> Sl.over (Sl.lensProps (['a', 'b', 'c']))
.         (S.add (1))
.         (example)
{a: {b: {c: 2}}}

Maybe

Wrapping value in Maybe depending on predicate

> Sl.toMaybe (x => !!x) (null)
Nothing

> Sl.toMaybe (x => !!x) (undefined)
Nothing

> Sl.toMaybe (x => !!x) (1)
Just (1)

Either

Convert to Either depending on predicate

> const toEven = Sl.toEither (x => x % 2 === 0)
.                            (x => `${x} is not a even number`);

> toEven (1)
Left ("1 is not a even number")

> toEven (2)
Right (2)

Fluture

Apply a function that return a Fluture on each item of an array and return a Fluture

> const array = [1, 2, 3, 4, 5];
> const f1 = Sl.flMap (1) (x => resolve (1 + x)) (array);
> const f2 = Sl.flMap (1) (x => reject ("error: " + x)) (array);

> fork (log ('rejection')) (log ('resolution')) (f1)
[resolution]: [2, 3, 4, 5, 6]

> fork (log ('rejection')) (log ('resolution')) (f2)
[rejection]: "error: 1"

Convert to a Fluture depending on predicate

> const toOdd = Sl.toFluture (x => x % 2 !== 0)
.                            (x => `${x} is not a odd number`);

> fork (log ('rejection')) (log ('resolution')) (toOdd (2))
[rejection]: "2 is not a odd number"

> fork (log ('rejection')) (log ('resolution')) (toOdd (1))
[resolution]: 1

Convert a Maybe to a Fluture

> const f1 = Sl.maybeToFluture ("not a number") (S.Just (1));
> const f2 = Sl.maybeToFluture ("not a number") (S.Nothing);

> fork (log ('rejection')) (log ('resolution')) (f1)
[resolution]: 1

> fork (log ('rejection')) (log ('resolution')) (f2)
[rejection]: "not a number"

Convert an Either to a Fluture

> const f1 = Sl.eitherToFluture (S.Right (1));
> const f2 = Sl.eitherToFluture (S.Left ("error"));

> fork (log ('rejection')) (log ('resolution')) (f1)
[resolution]: 1

> fork (log ('rejection')) (log ('resolution')) (f2)
[rejection]: "error"