source: node_modules/ramda-adjunct/src/cata.js

main
Last change on this file was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 3.0 KB
Line 
1import { curry } from 'ramda';
2
3import isFunction from './isFunction';
4
5/**
6 * The catamorphism is a way of folding a type into a value.
7 *
8 * **Either**
9 *
10 * If the either is right then the right function will be executed with
11 * the `right` value and the value of the function returned. Otherwise the left function
12 * will be called with the `left` value.
13 *
14 * **Maybe**
15 *
16 * If the maybe is Some than the right function will be executed with the `some` value and the value of the function
17 * returned. Otherwise the left function with be called without an argument.
18 *
19 * **Result**
20 *
21 * If the result is Ok than the right function will be executed with the `Ok` value and the value of the function
22 * returned. Otherwise the left function will be called with the `Error` value.
23 *
24 * **Validation**
25 *
26 * If the validation is Success than the right function will be executed with the `Success` value and the value of the function
27 * returned. Otherwise the left function will be called with the `Failure` value.
28 *
29 * Supported monadic libraries: {@link https://monet.github.io/monet.js/|monet.js}, {@link https://folktale.origamitower.com/|folktale}, {@link https://github.com/ramda/ramda-fantasy|ramda-fantasy}
30 *
31 * @func cata
32 * @memberOf RA
33 * @since {@link https://char0n.github.io/ramda-adjunct/1.4.0|v1.4.0}
34 * @category Function
35 * @sig (a -> b) -> (a -> c) -> Cata a -> b | c
36 * @param {Function} leftFn The left function that consumes the left value
37 * @param {Function} rightFn The right function that consumes the right value
38 * @param {Cata} catamorphicObj Either, Maybe or any other type with catamorphic capabilities (`cata` or `either` method)
39 * @return {*}
40 * @see {@link https://monet.github.io/monet.js/#cata|cata explained}
41 * @example
42 *
43 * // Either
44 * const eitherR = Either.Right(1);
45 * const eitherL = Either.Left(2);
46 *
47 * RA.cata(identity, identity, eitherR); //=> 1
48 * RA.cata(identity, identity, eitherL); //=> 2
49 *
50 * // Maybe
51 * const maybeSome = Maybe.Some(1);
52 * const maybeNothing = Maybe.Nothing();
53 *
54 * RA.cata(identity, identity, maybeSome); //=> 1
55 * RA.cata(identity, identity, maybeNothing); //=> undefined
56 */
57const catamorphism = curry((leftFn, rightFn, catamorphicObj) => {
58 // folktale support
59 if (isFunction(catamorphicObj.matchWith)) {
60 return catamorphicObj.matchWith({
61 // Result type
62 Ok: ({ value }) => rightFn(value),
63 Error: ({ value }) => leftFn(value),
64 // Maybe type
65 Just: ({ value }) => rightFn(value),
66 Nothing: () => leftFn(undefined),
67 // Validation type
68 Success: ({ value }) => rightFn(value),
69 Failure: ({ value }) => leftFn(value),
70 });
71 }
72
73 if (isFunction(catamorphicObj.cata)) {
74 return catamorphicObj.cata(leftFn, rightFn);
75 }
76
77 if (isFunction(catamorphicObj.getOrElse)) {
78 const elseValue = `RA.cata${Math.random()}`;
79 const value = catamorphicObj.getOrElse(elseValue);
80 return value === elseValue ? leftFn() : rightFn(value);
81 }
82
83 return catamorphicObj.either(leftFn, rightFn);
84});
85
86export default catamorphism;
Note: See TracBrowser for help on using the repository browser.