Guest User

DAT PHP DOE

a guest
May 19th, 2015
329
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 7.98 KB | None | 0 0
  1. <?php
  2.  
  3. // range :: (Num a) => a -> a -> a -> [a]
  4. function range_($n1 = 0 , $n2 = 1, $n = INF) {
  5.     $mkSingleBoundChecker = function ($start, $bound) {
  6.         if($bound == $start) {
  7.             $op = '!=';
  8.         } else {
  9.             $op = $bound > $start
  10.                 ? '<'
  11.                 : '>';
  12.         }
  13.  
  14.         return op($op, $bound);
  15.     };
  16.  
  17.     $step         = $n2 - $n1;
  18.     $isOutOfBound = $mkSingleBoundChecker($n1, $n);
  19.     for($i = $n1; !$isOutOfBound($i) ; $i += $step ) {
  20.         yield $i;
  21.     }
  22. }
  23.  
  24.  
  25. // map :: (a -> b) -> [a] -> [b]
  26. function map(Callable $f, $xs) {
  27.     foreach ($xs as $x) {
  28.         yield $f($x);
  29.     }
  30. }
  31.  
  32.  
  33. // filter :: (a -> Bool) -> [a] -> [a]
  34. function filter(Callable $p, $xs) {
  35.     foreach ($xs as $x) {
  36.         if($p($x)){
  37.             yield $x;
  38.         }
  39.     }
  40. }
  41.  
  42. // take :: Int -> [a] -> [a]
  43. function take($n , $xs) {
  44.     //this is shit
  45.     $xs = toIter($xs);
  46.     $xs->rewind();
  47.  
  48.     $isValid = $xs->valid();
  49.     for ($i = 0; $i < $n ; $i++) {
  50.         yield $isValid
  51.             ? $xs->current()
  52.             : null;
  53.  
  54.         if($isValid) {
  55.             $xs->next();
  56.             $valid = $xs->valid();
  57.         }
  58.     }
  59. }
  60.  
  61. // intersperse :: a -> [a] -> [a]
  62. function intersperse($sep, $xs) {
  63.     foreach($xs as $x) {
  64.         yield $x;
  65.         yield $sep;
  66.     }
  67. }
  68.  
  69. // repeat :: a -> [a]
  70. function repeat($x, $n = INF) {
  71.     for ($i = 0; $i < $n ; $i++) {
  72.         yield $x;
  73.     }
  74. }
  75.  
  76. // cycle :: [a] -> [a]
  77. function cycle($xs) {
  78.     //cant rewind a generator... so we save it on the first pass..
  79.     //this is shit lol...
  80.     //use some reflexion for optimisation eventually
  81.     $xs_ = [];
  82.     foreach($xs as $x) {
  83.         yield $x;
  84.         $xs_[] = $x;
  85.     }
  86.     unset($xs);
  87.  
  88.     foreach(new infiniteIterator(new arrayIterator($xs_)) as $x) {
  89.         yield $x;
  90.     }
  91. }
  92.  
  93. // concat :: [[a]] -> [a]
  94. function concat($xss) {
  95.     foreach ($xss as $xs) {
  96.         foreach($xs as $x) {
  97.             yield $x;
  98.         }
  99.     }
  100. }
  101.  
  102. // append :: [a] -> [a] -> [a]
  103. function append($xs, $ys) {
  104.     foreach ([$xs, $ys] as $xs) {
  105.         foreach($xs as $x) {
  106.             yield $x;
  107.         }
  108.     }
  109. }
  110.  
  111. // cons :: a -> [a] -> [a]
  112. function cons($x, $xs) {
  113.     yield $x;
  114.     foreach ($xs as $x) {
  115.         yield $x;
  116.     }
  117. }
  118.  
  119. // toIter :: [a] -> [a]
  120. function toIter($xs) {
  121.     $f = function () use ($xs){
  122.         foreach ($xs as $value) {
  123.             yield $value;
  124.         }
  125.     };
  126.  
  127.     return $f($xs);
  128. }
  129.  
  130. // iterToArray :: [a] -> [a]
  131. function itertoArray($xs) {
  132.     return iterator_to_array($xs);
  133. }
  134.  
  135. // takeWhile :: (a -> Bool) -> [a] -> [a]
  136. function takeWhile(Callable $p, $xs) {
  137.     foreach($xs as $x) {
  138.         if(!$p($x)) {
  139.             beak;
  140.         }
  141.         yield $x;
  142.     }
  143. }
  144.  
  145. // dropWhile :: (a -> Bool) -> [a] -> [a]
  146. function dropWhile(Callable $p, $xs) {
  147.     foreach($xs as $x) {
  148.         if($p($x)) {
  149.             continue;
  150.         }
  151.         yield $x;
  152.     }
  153. }
  154.  
  155.  
  156. // head :: [a] -> a
  157. function head($xs) {
  158.     foreach($xs as $x) {
  159.         return $x;
  160.     }
  161. }
  162.  
  163. // tail :: [a] -> [a]
  164. function tail($xs) {
  165.     $isHead = true;
  166.     foreach($xs as $x) {
  167.         if ($isHead) {
  168.             $isHead = false;
  169.             continue;
  170.         }
  171.         yield $x;
  172.     }
  173. }
  174.  
  175. // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
  176. function zipWith(Callable $f, $xs, $ys) {
  177.     throw new Exception("IMPLEMENT MEEEEEE Y_Y");
  178. }
  179.  
  180. //*************************** STRICT ************************************
  181. //*************************** STRICT ************************************
  182. //*************************** STRICT ************************************
  183.  
  184.  
  185. // op :: Binop -> a -> a -> b
  186. function op($op) {
  187.     //todo: be able to switch the params around..
  188.  
  189.     $ops = ['>='  => function ($x, $y) { return $x >=  $y; }
  190.            ,'<='  => function ($x, $y) { return $x <=  $y; }
  191.            ,'<'   => function ($x, $y) { return $x <   $y; }
  192.            ,'>'   => function ($x, $y) { return $x >   $y; }
  193.            ,'<>'  => function ($x, $y) { return $x <>  $y; }
  194.            ,'!='  => function ($x, $y) { return $x !=  $y; }
  195.            ,'!==' => function ($x, $y) { return $x !== $y; }
  196.            ,'=='  => function ($x, $y) { return $x ==  $y; }
  197.            ,'===' => function ($x, $y) { return $x === $y; }
  198.            ,'+'   => function ($x, $y) { return $x +   $y; }
  199.            ,'-'   => function ($x, $y) { return $x -   $y; }
  200.            ,'/'   => function ($x, $y) { return $x /   $y; }
  201.            ,'*'   => function ($x, $y) { return $x *   $y; }
  202.            ,'%'   => function ($x, $y) { return $x %   $y; }];
  203.  
  204.     $f    = $ops[$op];
  205.     $args = func_get_args();
  206.     switch (func_num_args()) {
  207.         case 1:
  208.             return $f;
  209.         break;
  210.         case 2:
  211.             return function($x) use ($f, $args) {
  212.                 return $f($args[1], $x);
  213.             };
  214.         break;
  215.         case 3:
  216.             return $f($args[1], $args[2]);
  217.         break;
  218.         default:
  219.             throw new Exception("GET A BRAIN! MORANS: (╯°□°)╯︵ ┻━┻", 999999999);
  220.         break;
  221.     }
  222. }
  223.  
  224. /*
  225. *  EXPLICIT partial application ...
  226. *  ex1 :
  227. *      $log = _e('file_put_contents','tmpfile','%1',FILE_APPEND);
  228. *      $log("require more minerals\n");
  229. *      $log("BLACK SHEEP WALL\n");
  230. *
  231. *  ex2 :
  232. */
  233. function _e(Callable $f) {
  234.     $args = array_slice(func_get_args(), 1);
  235.     return function() use ($f, $args) {
  236.         //TODO: move this shit outside the closure...
  237.         $args_ = [];
  238.         foreach($args as $arg) {
  239.             if(preg_match('/^%([1-9]*)$/', $arg, $matches)) {
  240.                 //func_get_arg is 0 based, we want to be 1 based.
  241.                 $args_[] = func_get_arg((int)$matches[1] - 1);
  242.             } else {
  243.                 $args_[] = $arg;
  244.             }
  245.         }
  246.         return call_user_func_array($f, $args_);
  247.     };
  248. }
  249.  
  250. /*
  251. *  partial application
  252. *  ex :
  253. *      $log = __('file_put_contents','tmpfile');
  254. *      $log("syntax error\n");
  255. *      $log("dick stuck in fan\n", FILE_APPEND);
  256. */
  257. function __(Callable $f) {
  258.     $args     = array_slice(func_get_args(), 1);
  259.  
  260.     return function() use ($f, $args) {
  261.         return call_user_func_array($f, array_merge($args, func_get_args()));
  262.     };
  263. }
  264.  
  265. /*
  266. * compose functions from right to left
  267. * ex:
  268. *  $f = comp(op('+',1),op('*',2));
  269. *  echo $f(1); // => 3
  270. */
  271. function comp() {
  272.     $fs = func_get_args();
  273.     return function ($x) use ($fs) {
  274.         return foldr(flip('apply'), $x, $fs);
  275.     };
  276. }
  277.  
  278. // apply :: (a -> b -> c) -> (b -> a -> c)
  279. function flip(Callable $f) {
  280.     return _e($f,'%2','%1');
  281. }
  282.  
  283. // apply :: (a -> b) -> a -> b
  284. function apply(Callable $f, $x) {
  285.     return $f($x);
  286. }
  287.  
  288. // identity :: a -> a
  289. function identity($x) {
  290.     return $x;
  291. }
  292.  
  293. // any :: (a -> Bool) -> [a] -> Bool
  294. function any(Callable $p, $xs) {
  295.     foreach($xs as $x) {
  296.         if($p($x)) {
  297.             return true;
  298.         }
  299.     }
  300.  
  301.     return false;
  302. }
  303.  
  304. // all :: (a -> Bool) -> [a] -> Bool
  305. function all(Callable $p, $xs) {
  306.     foreach($xs as $x) {
  307.         if(!$p($x)) {
  308.             return false;
  309.         }
  310.     }
  311.  
  312.     return true;
  313. }
  314.  
  315. // foldl :: (a -> b -> a) -> a -> [b] -> a
  316. function foldl(Callable $f, $acc, $xs) {
  317.     foreach($xs as $x) {
  318.         $acc = $f($acc, $x);
  319.     }
  320.     return $acc;
  321. }
  322.  
  323. // only works on array for now....
  324. // foldr :: (a -> b -> a) -> a -> [b] -> a
  325. function foldr(Callable $f, $acc, array $xs) {
  326.     while($x = array_pop($xs)) {
  327.         $acc = $f($acc, $x);
  328.     }
  329.     return $acc;
  330. }
  331.  
  332. // groupWith :: (a -> b) -> [a] -> [b => [a]]
  333. function groupWith(Callable $f, $xs) {
  334.     $xss = [];
  335.     foreach($xs as $x) {
  336.         $xss[$f($x)][] = $x;
  337.     }
  338.  
  339.     return $xss;
  340. }
  341.  
  342. // even :: Int -> Int -> Int -> [Int]
  343. function even($x) {
  344.     return $x % 2 == 0;
  345. }
  346.  
  347. // odd :: Int -> Int -> Int -> [Int]
  348. function odd($x) {
  349.     return $x % 2 != 0;
  350. }
  351.  
  352.  
  353. // add :: (Num a) => a -> a -> a
  354. function add($x, $y) {
  355.     return $x + $y;
  356. }
Advertisement
Add Comment
Please, Sign In to add comment