File tree Expand file tree Collapse file tree 3 files changed +50
-1
lines changed Expand file tree Collapse file tree 3 files changed +50
-1
lines changed Original file line number Diff line number Diff line change 8
8
"files" : [
9
9
" src/Nerd/Common/Arrays.php" ,
10
10
" src/Nerd/Common/Classes.php" ,
11
- " src/Nerd/Common/Strings.php"
11
+ " src/Nerd/Common/Strings.php" ,
12
+ " src/Nerd/Common/Functional.php"
12
13
]
13
14
},
14
15
"require-dev" : {
Original file line number Diff line number Diff line change
1
+ <?php
2
+
3
+ namespace Nerd \Common \Functional ;
4
+
5
+ /**
6
+ * Optimize given function for tail recursion.
7
+ *
8
+ * @param callable $fn
9
+ * @return \Closure
10
+ */
11
+ function tail (callable $ fn )
12
+ {
13
+ $ underCall = false ;
14
+ $ pool = [];
15
+ return function (...$ args ) use (&$ fn , &$ underCall , &$ pool ) {
16
+ $ result = null ;
17
+ $ pool [] = $ args ;
18
+ if (!$ underCall ) {
19
+ $ underCall = true ;
20
+ while ($ pool ) {
21
+ $ head = array_shift ($ pool );
22
+ $ result = $ fn (...$ head );
23
+ }
24
+ $ underCall = false ;
25
+ }
26
+ return $ result ;
27
+ };
28
+ }
Original file line number Diff line number Diff line change
1
+ <?php
2
+
3
+ namespace tests ;
4
+
5
+ use function Nerd \Common \Functional \tail ;
6
+ use PHPUnit \Framework \TestCase ;
7
+
8
+ class FunctionalTest extends TestCase
9
+ {
10
+ public function testTailRecursion ()
11
+ {
12
+ $ func = tail (function ($ max , $ acc = 0 ) use (&$ func ) {
13
+ if ($ max == $ acc ) {
14
+ return $ acc ;
15
+ }
16
+ return $ func ($ max , $ acc + 1 );
17
+ });
18
+ $ this ->assertEquals (10000 , $ func (10000 ));
19
+ }
20
+ }
You can’t perform that action at this time.
0 commit comments