├── readme.md ├── initials.php ├── matrix.php ├── LICENSE └── lib.php /readme.md: -------------------------------------------------------------------------------- 1 | ## Code for my "Functional programming in PHP" talk 2 | 3 | Link to the slides: 4 | [https://speakerdeck.com/pwm/functional-programming-in-php](https://speakerdeck.com/pwm/functional-programming-in-php) 5 | 6 | Link to the video: 7 | [https://www.youtube.com/watch?v=pWQV1x3YIJM&t=1m0s](https://www.youtube.com/watch?v=pWQV1x3YIJM&t=1m0s) 8 | 9 | -------------------------------------------------------------------------------- /initials.php: -------------------------------------------------------------------------------- 1 | getNumberOfRequiredParameters() 9 | ? curry($f, ...$args) 10 | : $f(...$args); 11 | })(array_merge($args, $partialArgs)); 12 | }; 13 | } 14 | 15 | // The identity function 16 | // a -> a 17 | $id = function ($x) { return $x; }; 18 | 19 | // Function composition operator aka. little circle 20 | // (b -> c) -> (a -> b) -> (a -> c) 21 | $o = curry(function ($g, $f) { 22 | return function ($x) use ($g, $f) { 23 | return $g($f($x)); 24 | }; 25 | }); 26 | 27 | // The Y fixed point combinator in applicative-order form 28 | // It transforms "pseudo recursive" functions to recursive functions 29 | // λf.(λx.f (λv.x x v)) (λx.f (λv.x x v)) 30 | $Y = function ($f) { 31 | return 32 | (function ($x) use ($f) { return $f(function ($v) use ($x) { return $x($x)($v); }); }) 33 | (function ($x) use ($f) { return $f(function ($v) use ($x) { return $x($x)($v); }); }); 34 | }; 35 | 36 | // Right fold, the "essence" of recursion on lists (made recursive via the Y combinator) 37 | // (a -> b -> b) -> b -> [a] -> b 38 | $foldr = $Y(function ($foldr) { 39 | return curry(function ($f, $v, $l) use ($foldr) { 40 | return count($l) > 0 41 | ? $f($l[0])($foldr($f)($v)(array_slice($l, 1))) 42 | : $v; 43 | }); 44 | }); 45 | 46 | // Map, expressed by foldr 47 | // (a -> b) -> [a] -> [b] 48 | $map = curry(function ($f, $l) use ($foldr) { 49 | return $foldr 50 | (curry(function ($x, $v) use ($f) { return array_merge([$f($x)], $v); })) 51 | ([]) 52 | ($l); 53 | }); 54 | 55 | // Filter, expressed by foldr 56 | // (a -> Bool) -> [a] -> [a] 57 | $filter = curry(function ($p, $l) use ($foldr) { 58 | return $foldr 59 | (curry(function ($x, $v) use ($p) { return $p($x) ? array_merge([$x], $v) : $v; })) 60 | ([]) 61 | ($l); 62 | }); 63 | 64 | // Composition of a list of functions 65 | // compose :: [a -> a] -> (a -> a) 66 | $compose = $foldr($o)($id); 67 | --------------------------------------------------------------------------------