Skip to content

Commit

Permalink
feat: add cata
Browse files Browse the repository at this point in the history
Closes #58
  • Loading branch information
char0n committed Apr 27, 2017
1 parent 331d0ad commit 1c6fdc6
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 4 deletions.
26 changes: 26 additions & 0 deletions src/cata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { invoker } from 'ramda';

/**
* The catamorphism for either. If the either is right than the right function will be executed with
* the right value and the value of the function returned. Otherwise the left function
* will be called with the left value.
*
* @func cata
* @memberOf RA
* @since {@link https://char0n.github.io/ramda-adjunct/1.4.0|v1.4.0}
* @category Function
* @sig (a -> b) -> (a -> c) -> Either a -> b | c
* @param {*} val The value to test
* @return {*}
* @see {@link RA.isNotArray|isNotArray}
* @example
*
* const eitherR = Either.Right(1);
* const eitherL = Either.Left(2);
*
* RA.cata(identity, identity, eitherR); //=> 1
* RA.cata(identity, identity, eitherL); //=> 2
*/
const cata = invoker(2, 'cata');

export default cata;
32 changes: 28 additions & 4 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@ declare var RA: RamdaAdjunct.Static;

declare namespace RamdaAdjunct {

interface Apply {
app: Function;
interface Functor<T> {
map<U>(fn: (t: T) => U): Functor<U>;
}

interface Apply<T> extends Functor<T> {
ap<U>(fn: Apply<(t: T) => U>): Apply<U>;
}

interface Catamorphism<T> {
cata<T1>(leftFn: (v: T1) => T, rightFn: (v: T1) => T): T;
}

interface Variadic<T1, T2> {
Expand Down Expand Up @@ -236,13 +244,29 @@ declare namespace RamdaAdjunct {
* "lifts" a function to be the specified arity, so that it may "map over" objects that satisfy
* the Apply spec of fantasy land.
*/
liftFN<T>(arity: number, fn: Variadic<Apply, T>): Apply
liftFN<T>(arity: number, fn: Variadic<Apply<T>, T>): Apply<T>

/**
* "lifts" a function of arity > 1 so that it may "map over" objects that satisfy
* the Apply spec of fantasy land.
*/
liftF<T>(fn: Variadic<Apply, T>): Apply
liftF<T>(fn: Variadic<Apply<T>, T>): Apply<T>

/**
* The catamorphism for either. If the either is right than the right function will be executed with
* the right value and the value of the function returned. Otherwise the left function
* will be called with the left value.
*/
cata<V1, V2, T1, T2>(leftFn: (leftValue: V1) => T1, rightFn: (rightValue: V2) => T2, either: Catamorphism<V1|V2>): T1|T2;
cata<V1, V2, T1, T2>(leftFn: (leftValue: V1) => T1, rightFn: (rightValue: V2) => T2): {
(either: Catamorphism<V1|V2>): T1|T2;
};
cata<V1, V2, T1, T2>(leftFn: (leftValue: V1) => T1): {
(rightFn: (rightValue: V2) => T1, either: Catamorphism<V1|V2>): T1|T2;
(rightFn: (rightValue: V2) => T1): {
(either: Catamorphism<V1|V2>): T1|T2;
}
}
}

}
Expand Down
3 changes: 3 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import stubUndefined from './stubUndefined';
import noop from './noop';
import liftFN from './liftFN';
import liftF from './liftF';
import cata from './cata';
// List
import pickIndexes from './pickIndexes';
import list from './list';
Expand Down Expand Up @@ -90,6 +91,7 @@ export { default as stubUndefined } from './stubUndefined';
export { default as noop } from './noop';
export { default as liftFN } from './liftFN';
export { default as liftF } from './liftF';
export { default as cata } from './cata';
// List
export { default as pickIndexes } from './pickIndexes';
export { default as list } from './list';
Expand Down Expand Up @@ -144,6 +146,7 @@ const RA = {
noop,
liftFN,
liftF,
cata,
// List
pickIndexes,
list,
Expand Down
31 changes: 31 additions & 0 deletions test/cata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Either } from 'monet';
import { identity } from 'ramda';
import chai from 'chai';

import RA from '../src/index';
import eq from './shared/eq';

describe('cata', function() {
const eitherR = Either.Right(1);
const eitherL = Either.Left(2);

it('tests an Either for catamorphism', function() {
eq(RA.cata(identity, identity, eitherR), 1);
eq(RA.cata(identity, identity, eitherL), 2);
});

it('test currying', function() {
eq(RA.cata(identity)(identity)(eitherR), 1);
eq(RA.cata(identity, identity)(eitherL), 2);
});

it('tests left for catamorphism without functions', function() {
chai.assert.throws(RA.cata.bind(null, null, identity, eitherL), TypeError);
eq(RA.cata(identity, null, eitherL), 2);
});

it('tests right for catamorphism without functions', function() {
chai.assert.throws(RA.cata.bind(null, identity, null, eitherR), TypeError);
eq(RA.cata(null, identity, eitherR), 1);
});
});

0 comments on commit 1c6fdc6

Please sign in to comment.