Created
April 26, 2016 00:26
-
-
Save catwarrior/73df75f0340e53bf43c8016ceb10f637 to your computer and use it in GitHub Desktop.
cljphp - implementing clojure std lib in php - http://blackwood.io/porting-clojure-php-better-functional-programming/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Returns the first item in an array. | |
*/ | |
function first(array $arr) { | |
$copy = array_slice($arr, 0, 1, true); | |
return array_shift($copy); | |
} | |
/** | |
* Returns the last item in an array. | |
*/ | |
function last(array $arr) { | |
$copy = array_slice($arr, 0, NULL, true); | |
return array_pop($copy); | |
} | |
/** | |
* Returns all but the first item in an array. | |
*/ | |
function rest(array $arr) { | |
return array_slice($arr, 1, NULL, true); | |
} | |
/** | |
* Returns all but the last item in an array. | |
*/ | |
function butlast(array $arr) { | |
$copy = array_slice($arr, 0, -1, true); | |
return $copy; | |
} | |
/** | |
* Returns true if the given predicate is true for all elements. | |
* credit: array_every and array_some.php | |
* https://gist.github.com/kid-icarus/8661319 | |
*/ | |
function every($callback, array $arr) { | |
foreach ($arr as $element) { | |
if (!$callback($element)) { | |
return FALSE; | |
} | |
} | |
return TRUE; | |
} | |
/** | |
* Returns true if the given predicate is true for at least one element. | |
* credit: array_every and array_some.php | |
* https://gist.github.com/kid-icarus/8661319 | |
*/ | |
function some($callback, array $arr) { | |
foreach ($arr as $element) { | |
if ($callback($element)) { | |
return TRUE; | |
} | |
} | |
return FALSE; | |
} | |
/** | |
* Returns true if the given predicate is not true for all elements. | |
*/ | |
function not_every($callback, array $arr) { | |
return !every($callable, $arr); | |
} | |
/** | |
* Alias call_user_func_array to apply. | |
*/ | |
function apply($callback, array $args) { | |
return call_user_func_array($callback, $args); | |
} | |
/** | |
* Takes a fn f and returns a fn that takes the same args as f, | |
* has the same effects, if any, and returns the opposite truth value. | |
*/ | |
function complement($f) { | |
return function() use ($f) { | |
$args = func_get_args(); | |
return !apply($f, $args); | |
}; | |
} | |
/** | |
* These are the standard arities for these functions in PHP. | |
* | |
* array_map($callback, $arr) | |
* array_filter($arr, $callback, $flag=NULL) | |
* array_reduce($arr, $callback, $initial=NULL) | |
* | |
* Lets normalize them. | |
*/ | |
/** | |
* Applies to each item in array, return new array. | |
*/ | |
function map($callback, array $arr) { | |
return array_map($callback, $arr); | |
} | |
/** | |
* Return a new array with elements for which predicate returns true. | |
*/ | |
function filter($callback, array $arr, $flag=0) { | |
return array_filter($arr, $callback, $flag); | |
} | |
/** | |
* Return a new array with elements for which predicate returns false. | |
*/ | |
function remove($callback, array $arr, $flag=0) { | |
return filter(complement($callback), $arr, $flag); | |
} | |
/** | |
* cons(truct) | |
* Returns a new array where x is the first element and $arr is the rest. | |
*/ | |
function cons($x, array $arr) { | |
return array_merge(array($x), $arr); | |
} | |
/** | |
* conj(oin) | |
* Returns a new arr with the xs added. | |
* @param $arr | |
* @param & xs add'l args to be added to $arr. | |
*/ | |
function conj() { | |
$args = func_get_args(); | |
$arr = first($args); | |
return array_merge($arr, rest($args)); | |
} | |
/** | |
* Alias array_merge to concat. | |
*/ | |
function concat() { | |
$arrs = func_get_args(); | |
return apply('array_merge', $arrs); | |
} | |
/** | |
* Returns a sequence of the first item in each collection then the second, etc. | |
*/ | |
function interleave() { | |
$arrs = func_get_args(); | |
$firsts = map('first', $arrs); | |
$rests = map('rest', $arrs); | |
if (every(function($a) { return !empty($a); }, $rests)) { | |
return concat($firsts, apply('interleave', $rests)); | |
} | |
return $firsts; | |
} | |
/** | |
* Alias implode to interpose. | |
*/ | |
function interpose($glue, array $pieces) { | |
return implode($glue, $pieces); | |
} | |
/** | |
* Returns true if number is even. | |
*/ | |
function even($n) { | |
return $n % 2 == 0; | |
} | |
/** | |
* Returns true if number is odd. | |
*/ | |
function odd($n) { | |
return complement('even'); | |
} | |
/** | |
* Takes a set of fns, returns new fn of variable args | |
* that applies the rightmost fn, and so on. | |
* Note on lambdas: | |
* https://php100.wordpress.com/2009/04/13/php-y-combinator/ | |
*/ | |
function comp() { | |
$fns = func_get_args(); | |
return function() use ($fns) { | |
$args = func_get_args(); | |
$l = function($xs, $fns) use (&$l) { | |
if (empty($fns)) { | |
return $xs; | |
} | |
return $l(apply(last($fns), (array)$xs), butlast($fns)); | |
}; | |
return $l($args, $fns); | |
}; | |
} | |
function juxt() { | |
$fns = func_get_args(); | |
return function() use ($fns) { | |
$args = func_get_args(); | |
$l = function($fn) use ($args) { | |
return apply($fn, $args); | |
}; | |
return map($l, $fns); | |
}; | |
} | |
/** | |
* @TODO | |
*/ | |
function loop(array $bindings) { | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment