Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- // range :: (Num a) => a -> a -> a -> [a]
- function range_($n1 = 0 , $n2 = 1, $n = INF) {
- $mkSingleBoundChecker = function ($start, $bound) {
- if($bound == $start) {
- $op = '!=';
- } else {
- $op = $bound > $start
- ? '<'
- : '>';
- }
- return op($op, $bound);
- };
- $step = $n2 - $n1;
- $isOutOfBound = $mkSingleBoundChecker($n1, $n);
- for($i = $n1; !$isOutOfBound($i) ; $i += $step ) {
- yield $i;
- }
- }
- // map :: (a -> b) -> [a] -> [b]
- function map(Callable $f, $xs) {
- foreach ($xs as $x) {
- yield $f($x);
- }
- }
- // filter :: (a -> Bool) -> [a] -> [a]
- function filter(Callable $p, $xs) {
- foreach ($xs as $x) {
- if($p($x)){
- yield $x;
- }
- }
- }
- // take :: Int -> [a] -> [a]
- function take($n , $xs) {
- //this is shit
- $xs = toIter($xs);
- $xs->rewind();
- $isValid = $xs->valid();
- for ($i = 0; $i < $n ; $i++) {
- yield $isValid
- ? $xs->current()
- : null;
- if($isValid) {
- $xs->next();
- $valid = $xs->valid();
- }
- }
- }
- // intersperse :: a -> [a] -> [a]
- function intersperse($sep, $xs) {
- foreach($xs as $x) {
- yield $x;
- yield $sep;
- }
- }
- // repeat :: a -> [a]
- function repeat($x, $n = INF) {
- for ($i = 0; $i < $n ; $i++) {
- yield $x;
- }
- }
- // cycle :: [a] -> [a]
- function cycle($xs) {
- //cant rewind a generator... so we save it on the first pass..
- //this is shit lol...
- //use some reflexion for optimisation eventually
- $xs_ = [];
- foreach($xs as $x) {
- yield $x;
- $xs_[] = $x;
- }
- unset($xs);
- foreach(new infiniteIterator(new arrayIterator($xs_)) as $x) {
- yield $x;
- }
- }
- // concat :: [[a]] -> [a]
- function concat($xss) {
- foreach ($xss as $xs) {
- foreach($xs as $x) {
- yield $x;
- }
- }
- }
- // append :: [a] -> [a] -> [a]
- function append($xs, $ys) {
- foreach ([$xs, $ys] as $xs) {
- foreach($xs as $x) {
- yield $x;
- }
- }
- }
- // cons :: a -> [a] -> [a]
- function cons($x, $xs) {
- yield $x;
- foreach ($xs as $x) {
- yield $x;
- }
- }
- // toIter :: [a] -> [a]
- function toIter($xs) {
- $f = function () use ($xs){
- foreach ($xs as $value) {
- yield $value;
- }
- };
- return $f($xs);
- }
- // iterToArray :: [a] -> [a]
- function itertoArray($xs) {
- return iterator_to_array($xs);
- }
- // takeWhile :: (a -> Bool) -> [a] -> [a]
- function takeWhile(Callable $p, $xs) {
- foreach($xs as $x) {
- if(!$p($x)) {
- beak;
- }
- yield $x;
- }
- }
- // dropWhile :: (a -> Bool) -> [a] -> [a]
- function dropWhile(Callable $p, $xs) {
- foreach($xs as $x) {
- if($p($x)) {
- continue;
- }
- yield $x;
- }
- }
- // head :: [a] -> a
- function head($xs) {
- foreach($xs as $x) {
- return $x;
- }
- }
- // tail :: [a] -> [a]
- function tail($xs) {
- $isHead = true;
- foreach($xs as $x) {
- if ($isHead) {
- $isHead = false;
- continue;
- }
- yield $x;
- }
- }
- // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
- function zipWith(Callable $f, $xs, $ys) {
- throw new Exception("IMPLEMENT MEEEEEE Y_Y");
- }
- //*************************** STRICT ************************************
- //*************************** STRICT ************************************
- //*************************** STRICT ************************************
- // op :: Binop -> a -> a -> b
- function op($op) {
- //todo: be able to switch the params around..
- $ops = ['>=' => function ($x, $y) { return $x >= $y; }
- ,'<=' => function ($x, $y) { return $x <= $y; }
- ,'<' => function ($x, $y) { return $x < $y; }
- ,'>' => function ($x, $y) { return $x > $y; }
- ,'<>' => function ($x, $y) { return $x <> $y; }
- ,'!=' => function ($x, $y) { return $x != $y; }
- ,'!==' => function ($x, $y) { return $x !== $y; }
- ,'==' => function ($x, $y) { return $x == $y; }
- ,'===' => function ($x, $y) { return $x === $y; }
- ,'+' => function ($x, $y) { return $x + $y; }
- ,'-' => function ($x, $y) { return $x - $y; }
- ,'/' => function ($x, $y) { return $x / $y; }
- ,'*' => function ($x, $y) { return $x * $y; }
- ,'%' => function ($x, $y) { return $x % $y; }];
- $f = $ops[$op];
- $args = func_get_args();
- switch (func_num_args()) {
- case 1:
- return $f;
- break;
- case 2:
- return function($x) use ($f, $args) {
- return $f($args[1], $x);
- };
- break;
- case 3:
- return $f($args[1], $args[2]);
- break;
- default:
- throw new Exception("GET A BRAIN! MORANS: (╯°□°)╯︵ â”»â”â”»", 999999999);
- break;
- }
- }
- /*
- * EXPLICIT partial application ...
- * ex1 :
- * $log = _e('file_put_contents','tmpfile','%1',FILE_APPEND);
- * $log("require more minerals\n");
- * $log("BLACK SHEEP WALL\n");
- *
- * ex2 :
- */
- function _e(Callable $f) {
- $args = array_slice(func_get_args(), 1);
- return function() use ($f, $args) {
- //TODO: move this shit outside the closure...
- $args_ = [];
- foreach($args as $arg) {
- if(preg_match('/^%([1-9]*)$/', $arg, $matches)) {
- //func_get_arg is 0 based, we want to be 1 based.
- $args_[] = func_get_arg((int)$matches[1] - 1);
- } else {
- $args_[] = $arg;
- }
- }
- return call_user_func_array($f, $args_);
- };
- }
- /*
- * partial application
- * ex :
- * $log = __('file_put_contents','tmpfile');
- * $log("syntax error\n");
- * $log("dick stuck in fan\n", FILE_APPEND);
- */
- function __(Callable $f) {
- $args = array_slice(func_get_args(), 1);
- return function() use ($f, $args) {
- return call_user_func_array($f, array_merge($args, func_get_args()));
- };
- }
- /*
- * compose functions from right to left
- * ex:
- * $f = comp(op('+',1),op('*',2));
- * echo $f(1); // => 3
- */
- function comp() {
- $fs = func_get_args();
- return function ($x) use ($fs) {
- return foldr(flip('apply'), $x, $fs);
- };
- }
- // apply :: (a -> b -> c) -> (b -> a -> c)
- function flip(Callable $f) {
- return _e($f,'%2','%1');
- }
- // apply :: (a -> b) -> a -> b
- function apply(Callable $f, $x) {
- return $f($x);
- }
- // identity :: a -> a
- function identity($x) {
- return $x;
- }
- // any :: (a -> Bool) -> [a] -> Bool
- function any(Callable $p, $xs) {
- foreach($xs as $x) {
- if($p($x)) {
- return true;
- }
- }
- return false;
- }
- // all :: (a -> Bool) -> [a] -> Bool
- function all(Callable $p, $xs) {
- foreach($xs as $x) {
- if(!$p($x)) {
- return false;
- }
- }
- return true;
- }
- // foldl :: (a -> b -> a) -> a -> [b] -> a
- function foldl(Callable $f, $acc, $xs) {
- foreach($xs as $x) {
- $acc = $f($acc, $x);
- }
- return $acc;
- }
- // only works on array for now....
- // foldr :: (a -> b -> a) -> a -> [b] -> a
- function foldr(Callable $f, $acc, array $xs) {
- while($x = array_pop($xs)) {
- $acc = $f($acc, $x);
- }
- return $acc;
- }
- // groupWith :: (a -> b) -> [a] -> [b => [a]]
- function groupWith(Callable $f, $xs) {
- $xss = [];
- foreach($xs as $x) {
- $xss[$f($x)][] = $x;
- }
- return $xss;
- }
- // even :: Int -> Int -> Int -> [Int]
- function even($x) {
- return $x % 2 == 0;
- }
- // odd :: Int -> Int -> Int -> [Int]
- function odd($x) {
- return $x % 2 != 0;
- }
- // add :: (Num a) => a -> a -> a
- function add($x, $y) {
- return $x + $y;
- }
Advertisement
Add Comment
Please, Sign In to add comment