curryN()   A
last analyzed

Complexity

Conditions 3
Paths 1

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3.054

Importance

Changes 0
Metric Value
cc 3
nc 1
nop 2
dl 0
loc 20
ccs 9
cts 11
cp 0.8182
crap 3.054
rs 9.6
c 0
b 0
f 0
1
<?php
2
namespace Aerophant\Ramda;
3
4
/**
5
 * @param mixed $data
6
 * @return \Closure
7
 */
8
function always()
9
{
10
  $always = function ($data) {
11
    return function () use ($data) {
12 3
      return $data;
13 3
    };
14 3
  };
15 3
  $arguments = func_get_args();
16 3
  $curried = curryN($always, 1);
17 3
  return call_user_func_array($curried, $arguments);
18
}
19
20
/**
21
 * @param callable $fn
22
 * @param array $args
23
 * @return string
24
 */
25
function apply()
26
{
27
  $apply = function (callable $fn, array $args) {
28 2
    return call_user_func_array($fn, $args);
29 2
  };
30 2
  $arguments = func_get_args();
31 2
  $curried = curryN($apply, 2);
32 2
  return call_user_func_array($curried, $arguments);
33
}
34
35
/**
36
 * @param callable $fn
37
 * @param mixed ...$args
38
 * @return string
39
 */
40
function call()
41
{
42 2
  $arguments = func_get_args();
43 2
  $length = count($arguments);
44
  switch ($length) {
45 2
    case 0:
46 1
          return __FUNCTION__;
47 2
    case 1:
48 1
      $fn = $arguments[0];
49
          return function (...$arguments) use ($fn) {
0 ignored issues
show
Bug Best Practice introduced by
The expression return function(...) { /* ... */ } returns the type callable which is incompatible with the documented return type string.
Loading history...
50 1
            return call_user_func_array($fn, $arguments);
51 1
          };
52
    default:
53 1
      $fn = $arguments[0];
54 1
      $arguments = dropFirst($arguments);
55 1
          return call_user_func_array($fn, $arguments);
56
  }
57
}
58
59
/**
60
 * @return callable
61
 * @throws \Exception
62
 */
63
function compose()
64
{
65 5
  $arguments = array_reverse(func_get_args());
66 5
  return call_user_func_array('Aerophant\Ramda\pipe', $arguments);
67
}
68
69
/**
70
 * @param string $class
71
 * @return \Closure
72
 */
73
function construct()
74
{
75
  $construct = function ($class) {
76
    return function () use ($class) {
77 3
      return new $class();
78 3
    };
79 3
  };
80 3
  $arguments = func_get_args();
81 3
  $curried = curryN($construct, 1);
82 3
  return call_user_func_array($curried, $arguments);
83
}
84
85
/**
86
 * @param callable $fn
87
 * @param int $numberOfArguments
88
 * @return \Closure
89
 */
90
function curryN(callable $fn, int $numberOfArguments)
91
{
92
  return function () use ($fn, $numberOfArguments) {
93 162
    $arguments = func_get_args();
94 162
    $length = count($arguments);
95 162
    if ($length > $numberOfArguments) {
96
      throw new \InvalidArgumentException(
97
        "Number of passed($length) parameters is greater than expected($numberOfArguments)"
98
      );
99
    }
100
    // NO CURRY
101 162
    if ($length == $numberOfArguments) {
102 162
      return call_user_func_array($fn, $arguments);
103
    }
104
    // AUTO CURRY
105
    $curriedFn = function () use ($fn, $arguments) {
106 153
      $curriedArguments = func_get_args();
107 153
      return call_user_func_array($fn, array_merge($arguments, $curriedArguments));
108 153
    };
109 153
    return curryN($curriedFn, $numberOfArguments - $length);
110 162
  };
111
}
112
113
/**
114
 * @param mixed $value
115
 * @return mixed|\Closure
116
 */
117
function identity()
118
{
119
  $identity = function ($value) {
120 1
    return $value;
121 1
  };
122 1
  $arguments = func_get_args();
123 1
  $curried = curryN($identity, 1);
124 1
  return call_user_func_array($curried, $arguments);
125
}
126
127
/**
128
 * @param callable $fn function to memorize result
129
 * @return callable memorized function
130
 */
131
function memoize()
132
{
133
  $memorize = function (callable $fn) {
134 1
    $result = null;
135
    return function () use (&$result, $fn) {
136 1
      if ($result === null) {
137 1
        $result = $fn();
138
      }
139 1
      return $result;
140 1
    };
141 1
  };
142 1
  $arguments = func_get_args();
143 1
  $curried = curryN($memorize, 1);
144 1
  return call_user_func_array($curried, $arguments);
145
}
146
147
/**
148
 * ((a, b, c, …, n) → x) → [a, b, c, …] → ((d, e, f, …, n) → x)
149
 * @param callable $fn
150
 * @param array $args
151
 * @return \Closure
152
 */
153
function partial(callable $fn, array $args)
154
{
155
  return function () use ($fn, $args) {
156 1
    $arguments = func_get_args();
157 1
    return call_user_func_array($fn, array_merge($args, $arguments));
158 1
  };
159
}
160
161
/**
162
 * ((a, b, c, …, n) → x) → [d, e, f, …, n] → ((a, b, c, …) → x)
163
 * @param callable $fn
164
 * @param array $args
165
 * @return \Closure
166
 */
167
function partialRight(callable $fn, array $args)
168
{
169
  return function () use ($fn, $args) {
170 3
    $arguments = func_get_args();
171 3
    return call_user_func_array($fn, array_merge($arguments, $args));
172 3
  };
173
}
174
175
/**
176
 * @return callable
177
 * @throws \Exception
178
 */
179
function pipe()
180
{
181 7
  $arguments = func_get_args();
182 7
  $length = count($arguments);
183 7
  if ($length === 0) {
184
    throw new \Exception("pipe requires at least one argument");
185
  }
186
  return function () use ($arguments) {
187 7
    $internalArguments = func_get_args();
188 7
    $initialValue = call_user_func_array($arguments[0], $internalArguments);
189
    $accumulator = function ($acc, $it) {
190 5
      return call_user_func_array($it, [$acc]);
191 7
    };
192 7
    return array_reduce(drop(0, $arguments), $accumulator, $initialValue);
193 7
  };
194
}
195