Skip to content

Commit

Permalink
feat: add Y combinator
Browse files Browse the repository at this point in the history
Closes #130
  • Loading branch information
char0n committed Dec 31, 2017
1 parent ecbcb82 commit dbdf6af
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/Y.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Y-combinator
*
* The Y combinator is an interesting function which only works with functional languages,
* showing how recursion can still be done even without any variable or function declarations,
* only functions and parameters
*
* @func Y
* @memberOf RA
* @since {@link https://char0n.github.io/ramda-adjunct/2.3.0|v2.3.0}
* @category Function
* @sig (a, ... -> b -> b) -> (a, ... -> b)
* @param {Function} le Recursive function maker
* @return {Function}
* @see {@link http://kestas.kuliukas.com/YCombinatorExplained/|Y combinator explained}
* @example
*
* const makeFact = givenFact => (n) => {
* if (n < 2) { return 1 }
* return n * givenFact(n - 1);
* };
*
* const factorial = RA.Y(makeFact);
*
* factorial(5); //=> 120
*/

const Y = le => (f => f(f))(g => le(x => (g(g))(x)));

export default Y;
9 changes: 9 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,15 @@ declare namespace RamdaAdjunct {
defaultWhen<DefVal, Val>(predicate: Function, defaultVal: DefVal): (val: Val) => DefVal | Val;
defaultWhen(predicate: Function): <DefVal, Val>(defaultVal: DefVal) => (val: Val) => DefVal | Val;

/**
* Y-combinator
*
* The Y combinator is an interesting function which only works with functional languages,
* showing how recursion can still be done even without any variable or function declarations,
* only functions and parameters
*/
Y(le: Function): Function;

/**
* Identity type.
*/
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export { default as curryRightN } from './curryRightN';
export { default as curryRight } from './curryRight';
export { default as resolveP } from './resolveP';
export { default as rejectP } from './rejectP';
export { default as Y } from './Y';
// List
export { default as pickIndexes } from './pickIndexes';
export { default as list } from './list';
Expand Down
16 changes: 16 additions & 0 deletions test/Y.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as RA from '../src/index';
import eq from './shared/eq';


describe('Y', function() {
it('tests for making a factorial function', function() {
const makeFact = givenFact => (n) => {
if (n < 2) { return 1 }
return n * givenFact(n - 1);
};

const factorial = RA.Y(makeFact);

eq(factorial(5), 120);
});
});

0 comments on commit dbdf6af

Please sign in to comment.