Skip to content

Commit 9ee6f60

Browse files
committed
Solutions
1 parent 398e74c commit 9ee6f60

File tree

2 files changed

+107
-4
lines changed

2 files changed

+107
-4
lines changed

source/index.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import curry from './curry';
2+
3+
export const add2 = a => b => a + b;
4+
5+
export const add3 = curry((a, b, c) => a + b + c);
6+
7+
export const inc = add2(1);
8+
9+
export const compose2 = (f, g) => x => f(g(x));
10+
11+
export const trace = label => value => {
12+
console.log(`${ label }: ${ JSON.stringify(value) }`);
13+
return value;
14+
};
15+
16+
export const compose = (...fns) => x => fns.reduceRight((acc, fn) => fn(acc), x);

source/test.js

Lines changed: 91 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,97 @@
1+
// ES6 Curry & Function Composition
2+
13
import test from 'tape';
4+
import { add2 } from './index';
5+
import { add3 } from './index';
6+
import { inc } from './index';
7+
import { compose2 } from './index';
8+
import { trace } from './index';
9+
import { compose } from './index';
10+
11+
// What is currying?
12+
// add2(a) => b => Number
13+
test('add2(a) => b => Number', assert => {
14+
const msg = 'should take two numbers and return the sum';
15+
16+
const actual = add2(1)(2);
17+
const expected = 3;
18+
19+
assert.same(actual, expected, msg);
20+
assert.end();
21+
});
22+
23+
// What is partial application?
24+
// add3(a) => b => c => Number
25+
test('add3(a) => b => c => Number', assert => {
26+
const msg = 'should auto-curry arguments and return the sum';
27+
28+
const expected = 6;
29+
30+
assert.same(add3(1, 2, 3), expected, msg);
31+
assert.same(add3(1)(2)(3), expected, msg);
32+
assert.same(add3(1)(2, 3), expected, msg);
33+
assert.same(add3(1, 2)(3), expected, msg);
34+
assert.end();
35+
});
36+
37+
// What is point-free style?
38+
// inc(n) => Number
39+
test('inc(n) => Number', assert => {
40+
const msg = 'should take a number a and return the sum of a and 1';
41+
42+
const actual = inc(4);
43+
const expected = 5;
44+
45+
assert.same(actual, expected, msg);
46+
assert.end();
47+
});
48+
49+
// What is function composition?
50+
// compose2(f: Function, g: Function) => Function
51+
// Given functions f and g, return the composition f ∘ g (f after g).
52+
// (f ∘ g)(x) = f(g(x))
53+
test('compose2(f: Function, g: Function) => Function', assert => {
54+
const msg = 'should take two functions, f & g, and return f ∘ g';
55+
56+
const g = n => n + 1;
57+
const f = n => n * 2;
58+
const h = compose2(f, g);
59+
60+
const actual = h(20);
61+
const expected = 42;
62+
63+
assert.same(actual, expected, msg);
64+
assert.end();
65+
});
66+
67+
// trace
68+
test('trace(label) => v => v, effects(log to console)', assert => {
69+
const msg = 'should take a label and value and log, "label: value"';
70+
71+
const actual = trace('foo')('bar');
72+
const expected = 'bar';
73+
74+
assert.same(actual, expected, msg);
75+
assert.end();
76+
});
77+
78+
// How does currying help with function composition?
79+
// compose(...fns: [...Functions]) => Function
80+
test('compose(...fns: [...Functions]) => Function', assert => {
81+
const msg = 'should take any number of functions and return their composition';
82+
83+
const g = n => n + 1;
84+
const f = n => n * 2;
285

3-
test('No tests yet!', assert => {
4-
const msg = 'should have tests';
86+
const h = compose(
87+
trace('after f'),
88+
f,
89+
trace('after g'),
90+
g
91+
);
592

6-
const actual = false;
7-
const expected = true;
93+
const actual = h(20);
94+
const expected = 42;
895

996
assert.same(actual, expected, msg);
1097
assert.end();

0 commit comments

Comments
 (0)