Completed
Push — master ( ec481a...cafea5 )
by Amine
8s
created

functions.php ➔ comparator()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 2
nop 0
dl 0
loc 11
rs 9.2
c 0
b 0
f 0
1
<?php namespace Tarsana\Functional;
2
3
/**
4
 * Functions dealing with functions.
5
 * @file
6
 */
7
8
/**
9
 * Returns a curried equivalent of the provided function.
10
 *
11
 * ```php
12
 * // A closure
13
 * $add = F\curry(function($x, $y) {
14
 *     return $x + $y;
15
 * });
16
 *
17
 * $add(1, 2); //=> 3
18
 * $addFive = $add(5); // this is a function
19
 * $addFive(1); //=> 6
20
 *
21
 * $sum = F\curry(function() use($add) {
22
 *     $numbers = func_get_args();
23
 *     return F\reduce($add, 0, $numbers);
24
 * });
25
 *
26
 * $sum(); //=> 0
27
 * $sum(1, 2, 3, 4); //=> 10
28
 * ```
29
 *
30
 * @signature (* -> a) -> (* -> a)
31
 * @param  callable $fn
32
 * @return callable
33
 */
34
function curry($fn) {
35
    return _curried_function($fn, _number_of_args($fn));
36
}
37
38
/**
39
 * Argument placeholder to use with curried functions.
40
 *
41
 * ```php
42
 * $minus = F\curry(function ($x, $y) { return $x - $y; });
43
 * $decrement = $minus(F\__(), 1);
44
 * $decrement(10); //=> 9
45
 *
46
 * $reduce = F\curry('array_reduce');
47
 * $sum = $reduce(F\__(), F\plus());
48
 * $sum([1, 2, 3, 4], 0); //=> 10
49
 * ```
50
 *
51
 * @signature * -> Placeholder
52
 * @return Tarsana\Functional\Placeholder
53
 */
54
function __() {
55
    return Placeholder::get();
56
}
57
58
/**
59
 * Apply the provided function to the list of arguments.
60
 *
61
 * ```php
62
 * F\apply('strlen', ['Hello']); //=> 5
63
 * $replace = F\apply('str_replace');
64
 * $replace(['l', 'o', 'Hello']); //=> 'Heooo'
65
 * ```
66
 *
67
 * @signature (*... -> a) -> [*] -> a
68
 * @param  callable $fn
0 ignored issues
show
Bug introduced by
There is no parameter named $fn. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
69
 * @param  array    $args
0 ignored issues
show
Bug introduced by
There is no parameter named $args. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
70
 * @return mixed
71
 */
72
function apply() {
73
    static $apply = false;
74
    $apply = $apply ?: curry(_f('_apply'));
75
    return _apply($apply, func_get_args());
76
}
77
78
/**
79
 * Performs left-to-right function composition.
80
 *
81
 * The leftmost function may have any arity;
82
 * the remaining functions must be unary.
83
 * The result of pipe is curried.
84
 * **Calling pipe() without any argument returns the `identity` function**
85
 * ```php
86
 * $double = function($x) { return 2 * $x; };
87
 * $addThenDouble = F\pipe(F\plus(), $double);
88
 * $addThenDouble(2, 3); //=> 10
89
 * ```
90
 *
91
 * @signature (((a, b, ...) -> o), (o -> p), ..., (y -> z)) -> ((a, b, ...) -> z)
92
 * @param  callable $fns...
0 ignored issues
show
Bug introduced by
There is no parameter named $fns.... Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
93
 * @return callable
94
 */
95
function pipe() {
96
    $fns = func_get_args();
97
    if(count($fns) < 1)
98
        return identity();
99
    return curry(function () use ($fns) {
100
        $result = _apply(array_shift($fns), func_get_args());
101
        foreach ($fns as $fn) {
102
            $result = $fn($result);
103
        }
104
        return $result;
105
    });
106
}
107
108
/**
109
 * A function that takes one argument and
110
 * returns exactly the given argument.
111
 *
112
 * ```php
113
 * F\identity('Hello'); //=> 'Hello'
114
 * F\identity([1, 2, 3]); //=> [1, 2, 3]
115
 * F\identity(null); //=> null
116
 * ```
117
 *
118
 * @signature * -> *
119
 * @return mixed
120
 */
121
function identity() {
122
    static $identity = false;
123
    $identity = $identity ?: curry(function($value) {
124
        return $value;
125
    });
126
    return _apply($identity, func_get_args());
127
}
128
129
/**
130
 * Returns a function which whenever called will return the specified value.
131
 *
132
 * ```php
133
 * $five = F\give(5);
134
 * $five(); //=> 5
135
 * $null = F\give(null);
136
 * $null(); //=> null
137
 * ```
138
 *
139
 * @signature a -> (* -> a)
140
 * @param  mixed $value
0 ignored issues
show
Bug introduced by
There is no parameter named $value. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
141
 * @return callable
142
 */
143
function give() {
144
    static $give = false;
145
    $give = $give ?: curry(function($value) {
146
        return function() use($value) {
147
            return $value;
148
        };
149
    });
150
    return _apply($give, func_get_args());
151
}
152
153
/**
154
 * Takes many predicates and returns a new predicate that
155
 * returns `true` only if all predicates are satisfied.
156
 *
157
 * If no predicate is given as argument, this function
158
 * will return an always passing predicate.
159
 * ```php
160
 * $betweenOneAndTen = F\all(F\gte(F\__(), 1), F\lte(F\__(), 10));
161
 * $betweenOneAndTen(5); //=> true
162
 * $betweenOneAndTen(0); //=> false
163
 * $alwaysTrue = F\all();
164
 * $alwaysTrue(1); //=> true
165
 * $alwaysTrue(null); //=> true
166
 * ```
167
 *
168
 * @signature ((a -> Boolean), ..., (a -> Boolean)) -> (a -> Boolean)
169
 * @param  callable $predicates...
0 ignored issues
show
Bug introduced by
There is no parameter named $predicates.... Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
170
 * @return callable
171
 */
172 View Code Duplication
function all() {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
173
    $predicates = func_get_args();
174
    return function($value) use($predicates) {
175
        return reduce(function($result, $predicate) use($value) {
176
            return $result && $predicate($value);
177
        }, true, $predicates);
178
    };
179
}
180
181
/**
182
 * Takes many predicates and returns a new predicate that
183
 * returns `true` if any of the predicates is satisfied.
184
 *
185
 * If no predicate is given as argument, this function
186
 * will return an always non-passing predicate.
187
 * ```php
188
 * $startsOrEndsWith = function($text) {
189
 *     return F\any(F\startsWith($text), F\endsWith($text));
190
 * };
191
 * $test = $startsOrEndsWith('b');
192
 * $test('bar'); //=> true
193
 * $test('bob'); //=> true
194
 * $test('foo'); //=> false
195
 * $alwaysFlase = F\any();
196
 * $alwaysFlase(1); //=> false
197
 * $alwaysFlase(null); //=> false
198
 * ```
199
 *
200
 * @signature ((a -> Boolean), ..., (a -> Boolean)) -> (a -> Boolean)
201
 * @param  callable $predicates...
0 ignored issues
show
Bug introduced by
There is no parameter named $predicates.... Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
202
 * @return callable
203
 */
204 View Code Duplication
function any() {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
205
    $predicates = func_get_args();
206
    return function($value) use($predicates) {
207
        return reduce(function($result, $predicate) use($value) {
208
            return $result || $predicate($value);
209
        }, false, $predicates);
210
    };
211
}
212
213
/**
214
 * Takes a function `f` and returns a function `g` so that if `f` returns
215
 * `x` for some arguments; `g` will return `! x` for the same arguments.
216
 *
217
 * Note that `complement($fn) == pipe($fn, not())`.
218
 * ```php
219
 * $isOdd = function($number) {
220
 *     return 1 == $number % 2;
221
 * };
222
 *
223
 * $isEven = F\complement($isOdd);
224
 *
225
 * $isEven(5); //=> false
226
 * $isEven(8); //=> true
227
 * ```
228
 *
229
 * @signature (* -> ... -> *) -> (* -> ... -> Boolean)
230
 * @param  callable $fn
0 ignored issues
show
Bug introduced by
There is no parameter named $fn. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
231
 * @return callable
232
 */
233
function complement() {
234
    static $complement = false;
235
    $complement = $complement ?: curry(function($fn) {
236
        return pipe($fn, not());
237
    });
238
    return _apply($complement, func_get_args());
239
}
240
241
/**
242
 * Takes a function telling if the first argument is less then the second, and return a compare function.
243
 *
244
 * A compare function returns `-1`, `0`, or `1` if the first argument is considered
245
 * to be respectively less than, equal to, or greater than the second.
246
 * ```php
247
 * $users = [
248
 *     ['name' => 'foo', 'age' => 21],
249
 *     ['name' => 'bar', 'age' => 11],
250
 *     ['name' => 'baz', 'age' => 15]
251
 * ];
252
 *
253
 * usort($users, F\comparator(function($a, $b){
254
 *     return $a['age'] < $b['age'];
255
 * }));
256
 *
257
 * F\map(F\get('name'), $users); //=> ['bar', 'baz', 'foo']
258
 * ```
259
 *
260
 * @signature (a -> a -> Boolean) -> (a -> a -> Number)
261
 * @param  callable $fn
0 ignored issues
show
Bug introduced by
There is no parameter named $fn. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
262
 * @return callable
263
 */
264
function comparator() {
265
    static $comparator = false;
266
    $comparator = $comparator ?: curry(function($fn) {
267
        return function($a, $b) use($fn) {
268
            if ($fn($a, $b)) return -1;
269
            if ($fn($b, $a)) return 1;
270
            return 0;
271
        };
272
    });
273
    return _apply($comparator, func_get_args());
274
}
275
276