Skip to content

Instantly share code, notes, and snippets.

@ackintosh
Created February 2, 2013 06:35
Show Gist options
  • Save ackintosh/4696317 to your computer and use it in GitHub Desktop.
Save ackintosh/4696317 to your computer and use it in GitHub Desktop.
Functional Programming in PHP
<?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