Passed
Pull Request — master (#6)
by Siwapun
04:52
created

call()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.7333
c 0
b 0
f 0
cc 3
nc 3
nop 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
      return $data;
13
    };
14
  };
15
  $arguments = func_get_args();
16
  $curried = curryN($always, 1);
17
  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
    return call_user_func_array($fn, $args);
29
  };
30
  $arguments = func_get_args();
31
  $curried = curryN($apply, 2);
32
  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
  $arguments = func_get_args();
43
  $length = count($arguments);
44
  switch ($length) {
45
    case 0:
46
          return __FUNCTION__;
47
    case 1:
48
      $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
            return call_user_func_array($fn, $arguments);
51
          };
52
    default:
53
      $fn = $arguments[0];
54
      $arguments = dropFirst($arguments);
55
          return call_user_func_array($fn, $arguments);
56
  }
57
}
58
59
/**
60
 * @return callable
61
 * @throws \Exception
62
 */
63
function compose()
64
{
65
  $arguments = array_reverse(func_get_args());
66
  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
      return new $class();
78
    };
79
  };
80
  $arguments = func_get_args();
81
  $curried = curryN($construct, 1);
82
  return call_user_func_array($curried, $arguments);
83
}
84
85
function curryN(callable $fn, int $numberOfArguments)
86
{
87
  return function () use ($fn, $numberOfArguments) {
88
    $arguments = func_get_args();
89
    $length = count($arguments);
90
    if ($length > $numberOfArguments) {
91
      throw new \InvalidArgumentException(
92
        "Number of passed($length) parameters is greater than expected($numberOfArguments)"
93
      );
94
    }
95
    // NO CURRY
96
    if ($length == $numberOfArguments) {
97
      return call_user_func_array($fn, $arguments);
98
    }
99
    // AUTO CURRY
100
    $curriedFn = function () use ($fn, $arguments) {
101
      $curriedArguments = func_get_args();
102
      return call_user_func_array($fn, array_merge($arguments, $curriedArguments));
103
    };
104
    return curryN($curriedFn, $numberOfArguments - $length);
105
  };
106
}
107
108
/**
109
 * ((a, b, c, …, n) → x) → [a, b, c, …] → ((d, e, f, …, n) → x)
110
 * @param callable $fn
111
 * @param array $args
112
 * @return \Closure
113
 */
114
function partial(callable $fn, array $args)
115
{
116
  return function () use ($fn, $args) {
117
    $arguments = func_get_args();
118
    return call_user_func_array($fn, array_merge($args, $arguments));
119
  };
120
}
121
122
/**
123
 * ((a, b, c, …, n) → x) → [d, e, f, …, n] → ((a, b, c, …) → x)
124
 * @param callable $fn
125
 * @param array $args
126
 * @return \Closure
127
 */
128
function partialRight(callable $fn, array $args)
129
{
130
  return function () use ($fn, $args) {
131
    $arguments = func_get_args();
132
    return call_user_func_array($fn, array_merge($arguments, $args));
133
  };
134
}
135
136
/**
137
 * @return callable
138
 * @throws \Exception
139
 */
140
function pipe()
141
{
142
  $arguments = func_get_args();
143
  $length = count($arguments);
144
  if ($length === 0) {
145
    throw new \Exception("pipe requires at least one argument");
146
  }
147
  return function () use ($arguments) {
148
    $internalArguments = func_get_args();
149
    $initialValue = call_user_func_array($arguments[0], $internalArguments);
150
    $accumulator = function ($acc, $it) {
151
      return call_user_func_array($it, [$acc]);
152
    };
153
    return array_reduce(drop(0, $arguments), $accumulator, $initialValue);
154
  };
155
}
156