Created
February 2, 2013 06:35
-
-
Save ackintosh/4696317 to your computer and use it in GitHub Desktop.
Functional Programming in PHP
This file contains 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 | |
class MyList implements ArrayAccess | |
{ | |
private $_values; | |
public function __construct($array = array()) | |
{ | |
$this->_values = $array; | |
} | |
public function cons($a) | |
{ | |
if (!is_int($a)) throw new InvalidArgumentException(); | |
array_unshift($this->_values, $a); | |
return $this; | |
} | |
public function head() | |
{ | |
return $this->_values[0]; | |
} | |
public function tail() | |
{ | |
return new MyList(array_slice($this->_values, 1)); | |
} | |
public function sum0() | |
{ | |
if (empty($this->_values)) return 0; | |
return $this->head() + $this->tail()->sum0(); | |
} | |
public function reduce($f, $a) | |
{ | |
if (empty($this->_values)) return $a; | |
return $f($this->head(), $this->tail()->reduce($f, $a)); | |
} | |
public function sum() | |
{ | |
return $this->reduce($this->add(), 0); | |
} | |
public function add() | |
{ | |
return function ($a, $b) { return $a + $b; }; | |
} | |
public function product() | |
{ | |
return $this->reduce($this->multiply(), 1); | |
} | |
public function multiply() | |
{ | |
return function ($a, $b) { return $a * $b; }; | |
} | |
public function any_true() | |
{ | |
return $this->reduce($this->_or(), false); | |
} | |
public function all_true() | |
{ | |
return $this->reduce($this->_and(), true); | |
} | |
public function _or() | |
{ | |
return function ($a, $b) { return ($a === true || $b === true); }; | |
} | |
public function _and() | |
{ | |
return function ($a, $b) { return $a === true && $b === true; }; | |
} | |
public function _cons() | |
{ | |
return function ($a, $b) { return $b->cons($a); }; | |
} | |
public function dup() | |
{ | |
return $this->reduce($this->_cons(), new MyList()); | |
} | |
public function append($ls) | |
{ | |
return $this->reduce($this->_cons(), $ls); | |
} | |
public function double_all() | |
{ | |
return $this->reduce($this->double_and_cons(), new MyList()); | |
} | |
public function double_and_cons() | |
{ | |
return function ($a, $ls) { return $ls->cons($a * 2); }; | |
} | |
public function offsetExists($offset) | |
{ | |
return isset($this->_values[$offset]); | |
} | |
public function offsetGet($offset) | |
{ | |
if (isset($this->_values[$offset])) { | |
return $this->_values[$offset]; | |
} | |
return null; | |
} | |
public function offsetSet($offset, $value) | |
{ | |
if (!is_int($offset)) throw new InvalidArgumentException("You can't use as a Hash."); | |
$this->_values[$offset] = $value; | |
} | |
public function offsetUnset($offset) | |
{ | |
unset($this->_values[$offset]); | |
} | |
} | |
$ma = new MyList(array(1, 2, 3, 4, 5)); | |
var_dump($ma->sum0());// 15 | |
$ma = new MyList(); | |
var_dump($ma->cons(1)->cons(2)->cons(3)->sum0());// 6 | |
$ma = new MyList(array(1, 2, 3, 4, 5)); | |
$r = $ma->reduce(function($a, $b) { return $a + $b; }, 0); | |
var_dump($r);// 15 | |
$ma = new MyList(array(1, 2, 3, 4, 5)); | |
var_dump($ma->sum());// 15 | |
$ma = new MyList(array(1, 2, 3, 4, 5)); | |
var_dump($ma->product());// 120 | |
$ma = new MyList(array(false, true, false)); | |
var_dump($ma->any_true());// true | |
var_dump($ma->all_true());// false | |
$ma = new MyList(array(true, true, true)); | |
var_dump($ma->any_true());// true | |
var_dump($ma->all_true());// true | |
$ma = new MyList(array(1, 2, 3)); | |
var_dump($ma->dup()); | |
var_dump($ma->append(new MyList(array(4, 5, 6)))); | |
$ma = new MyList(array(1, 2, 3, 4, 5)); | |
var_dump($ma->double_all()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment