-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy paththunkify.js
More file actions
109 lines (105 loc) · 2.6 KB
/
thunkify.js
File metadata and controls
109 lines (105 loc) · 2.6 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
const areAnyValuesPromises = require('./_internal/areAnyValuesPromises')
const promiseAll = require('./_internal/promiseAll')
const curry3 = require('./_internal/curry3')
const __ = require('./_internal/placeholder')
const funcApply2 = require('./_internal/funcApply2')
/**
* @name _thunkifyArgs
*
* @synopsis
* ```coffeescript [specscript]
* _thunkifyArgs(func function, context object, args Array) -> thunk
* ```
*/
function _thunkifyArgs(func, context, args) {
return function thunk() {
return func.apply(context, args)
}
}
/**
* @name thunkify
*
* @synopsis
* ```coffeescript [specscript]
* args Array<any>
*
* thunkify(func function, ...args) -> thunk ()=>func(...args)
* ```
*
* @description
* Creates a thunk from a function and arguments. A thunk takes no arguments, and when called, executes the other function with the arguments. The other function is said to be "thunkified".
*
* ```javascript [playground]
* const add = (a, b) => a + b
*
* const thunkAdd12 = thunkify(add, 1, 2)
*
* console.log(thunkAdd12()) // 3
* ```
*
* See also:
* * [eq](/docs/eq)
* * [thunkify.call](/docs/thunkify.call)
* * [always](/docs/always)
* * [curry](/docs/curry)
* * [__](/docs/__)
* * [Transducer.map](/docs/Transducer.map)
*
*/
const thunkify = function thunkify(func, ...args) {
if (areAnyValuesPromises(args)) {
return promiseAll(args).then(curry3(_thunkifyArgs, func, this, __))
}
return _thunkifyArgs(func, this, args)
}
/**
* @name thunkify.call
*
* @synopsis
* ```coffeescript [specscript]
* args Array<any>
*
* thunkify.call(func function, context object, ...args) -> thunk ()=>func(...args)
* ```
*
* @description
* Creates a thunk that calls a function with the specified context and arguments.
*
* ```javascript [playground]
* class Point {
* constructor(x, y) {
* this.x = x
* this.y = y
* }
*
* distanceTo() {
* const x2 = (point.x - this.x) ** 2
* const y2 = (point.y - this.y) ** 2
* return (x2 + y2) ** 0.5
* }
* }
*
* const point0 = new Point(0, 0)
* const point = new Point(3, 4)
*
* const thunk = thunkify.call(point0.distanceTo, point0, point)
*
* console.log(thunk())
* ```
*
* See also:
* * [eq](/docs/eq)
* * [thunkify](/docs/thunkify)
* * [always](/docs/always)
* * [curry](/docs/curry)
* * [__](/docs/__)
* * [Transducer.map](/docs/Transducer.map)
*
*/
thunkify.call = function thunkifyCall(func, context, ...args) {
if (areAnyValuesPromises(args)) {
return promiseAll(args).then(curry3(_thunkifyArgs, func, context, __))
}
return _thunkifyArgs(func, context, args)
}
module.exports = thunkify