forked from imteekay/functional-programming-learning-path
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcurrying.js
More file actions
112 lines (83 loc) · 2.81 KB
/
Copy pathcurrying.js
File metadata and controls
112 lines (83 loc) · 2.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
const log = (...args) => console.log(...args);
const add = (x) => (y) => x + y;
/***
const add = (x) => {
return (y) => {
Fix x = ?
x + y;
}
}
***/
const increment = add(1);
let one = 1;
let two = increment(one);
let three = increment(two);
log(two); // 2
log(three); // 3
const addTen = add(10);
log(addTen(10)); // 20
log(addTen(0)); // 10
// ---------------------------------------------------------------------------------------------
// Outside of function composition, currying is a useful abstraction we can use to specialize functions
// One example is to curry the map function
const map = fn => mappable => mappable.map(fn);
const arr = [1, 2, 3, 4, 5];
const isEven = n => n % 2 === 0;
const stripe = n => isEven(n) ? 'dark' : 'light';
const stripeAll = map(stripe);
const striped = stripeAll(arr);
log(striped); // => ['light', 'dark', 'light', 'dark', 'light']
const double = n => n * 2;
const doubleAll = map(double);
const doubled = doubleAll(arr);
log(doubled); // => [2, 4, 6, 8, 10]
// Get element by value from list of objects
// Using currying for specialized functions
const posts = [
{ id: '0001', title: 'Title 0001' },
{ id: '0002', title: 'Title 0002' },
{ id: '0003', title: 'Title 0003' },
{ id: '0004', title: 'Title 0004' }
]
const getFromBasic = (list, field) => (value) =>
list[list.map(el => el[field]).indexOf(value)];
const getByIdBasic = (list, field = "id") => getFromBasic(list, field);
let selected = getByIdBasic(posts)('0003');
log(selected);
const getFrom = (field) => (list) => (value) =>
list[list.map(el => el[field]).indexOf(value)];
const getById = getFrom('id');
const getByTitle = getFrom('title');
selected = getById(posts)('0003');
log(selected);
selected = getByTitle(posts)('Title 0004');
log(selected);
// ---------------------------------------------------------------------------------------------
/*
jQuery approach
$('some-css-class').on('click', callback);
*/
/*
How I want to use
- onClick(element, handler);
- onHover(element, handler);
*/
/*
A more generic approach
(event) => (element, handler) => fn
The idea is to use curry
- receive the event string first and return a new function
- the new function receives the element and the callback handler
- passing the event string first helps to create specialized functions (e.g. onClick and onHover)
*/
const eventListener = (event) => (element, handler) => element.addEventListener(event, handler);
const onClick = eventListener('click');
const onHover = eventListener('hover');
/*
Example: on click event for the vote button
This example runs page this StackOverflow page
https://stackoverflow.com/questions/6348494/addeventlistener-vs-onclick
*/
const voteUpButton = document.getElementsByClassName('js-vote-up-btn')[0];
const helloAlert = () => alert('Hello!');
onClick(voteUpButton, helloAlert);