Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
"phpunit/phpunit": "*"
},
"autoload": {
"psr-4": {
"Pairs\\": "src"
}
"files": [
"src/Pairs.php",
"src/Lists.php"
]
}
}
4 changes: 2 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions phpunit
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env php
<?php
/*
* This file is part of PHPUnit.
*
* (c) Sebastian Bergmann <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

if (version_compare('5.6.0', PHP_VERSION, '>')) {
fwrite(
STDERR,
'This version of PHPUnit requires PHP 5.6; using the latest version of PHP is highly recommended.' . PHP_EOL
);

die(1);
}

if (!ini_get('date.timezone')) {
ini_set('date.timezone', 'UTC');
}

require __DIR__ . '/vendor/autoload.php';

PHPUnit_TextUI_Command::main();
19 changes: 19 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>

<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="vendor/autoload.php"
>
<testsuites>
<testsuite name="Test Suite">
<directory>./tests/</directory>
</testsuite>
</testsuites>
</phpunit>
102 changes: 102 additions & 0 deletions src/Lists.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

namespace Lists;
use function Pairs\cons;
use function Pairs\car;
use function Pairs\cdr;
use function Pairs\toString;


/**
* Applies callable function $func to list $list
* @param callable $func function
* @param callable $list list
* @return result list
*/
function map(callable $func, callable $list) {
$map = function ($items, $acc) use (&$map, $func) {
if (is_null($items)) {
return reverse($acc);
}
return $map(cdr($items), cons($func(car($items)), $acc));
};

return $map($list, null);
}

/**
* Filters list $list using callable function $func
* @param callable $func function
* @param callable $list list
* @return result list
*/
function filter(callable $func, callable $list) {
$map = function ($func, $items) use (&$map) {
if ($items === null) {
return null;
} else {
$curr = car($items);
$rest = $map($func, cdr($items));
// filter
return $func($curr) ? cons($curr, $rest) : $rest;
}
};

return $map($func, $list);
}

/**
* Collapses the list $list using callable function $func
* @param callable $func function
* @param callable $list list
* @param mixed $acc
* @return result
*/
function reduce(callable $func, callable $list, $acc = null) {
$iter = function ($items, $acc) use (&$iter, $func) {
return is_null($items) ? $acc : $iter(cdr($items), $func(car($items), $acc));
};

return $iter($list, $acc);
}

/**
* Concatenates two lists
* @param pair $list1
* @param pair $list2
* @return new list
*/
function append(callable $list1, callable $list2)
{
if ($list1 === null) {
return $list2;
} else {
return cons(car($list1), append(cdr($list1), $list2));
}
}

/**
* Reverse list $list
* @param callable $list list
* @return result
*/
function reverse(callable $list) {
$iter = function ($items, $acc) use (&$iter) {
return is_null($items) ? $acc : $iter(cdr($items), cons(car($items), $acc));
};

return $iter($list, null);
}

/**
* Returns length of list
* @param callable $list list
* @return integer length
*/
function length($list) {
if ($list === null || !is_callable($list)) {
return 0;
} else {
return 1 + length(cdr($list));
}
}
2 changes: 1 addition & 1 deletion src/Pairs.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function toString($list)
$arr = [];
$iter = function ($items) use (&$arr, &$iter) {
if ($items != null) {
$arr[] = listToString(car($items));
$arr[] = toString(car($items));
$iter(cdr($items));
}

Expand Down
66 changes: 66 additions & 0 deletions tests/ListsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace Pairs\tests;


use function Pairs\cons;
use function Pairs\car;
use function Pairs\cdr;
use function Pairs\toString;


use function Lists\length;
use function Lists\reverse;
use function Lists\map;
use function Lists\filter;
use function Lists\reduce;

class ListsTest extends \PHPUnit_Framework_TestCase
{

public function testLength()
{
$list = cons(1,cons(2, cons(3, null)));
$this->assertEquals(3, length($list));

}

public function testReverse()
{
$list = cons(1, cons(2, cons(3, null)));
$expected = toString(cons(3, cons(2, cons(1, null))));
$this->assertEquals($expected, toString(reverse($list)));
}

public function testMap()
{
$list = cons(1, cons(2, cons(3, null)));
$expected = toString(cons(3, cons(4, cons(5, null))));
$map = map(function ($x) {
return $x + 2;
}, $list);
$this->assertEquals($expected, toString($map));
}

public function testFilter()
{
$list = cons(2, cons(3, cons(4, null)));
$expected = toString(cons(2, cons(4, null)));
$filter = filter(function ($x) {
return $x % 2 == 0;
}, $list);

$this->assertEquals(2, length($filter));
$this->assertEquals($expected, toString($filter));
}

public function testReduce()
{
$list = cons(1, cons(2, cons(3, null)));
$expected = 6;
$map = reduce(function ($x, $acc) {
return $x + $acc;
}, $list, 0);
$this->assertEquals($expected, $map);
}
}
2 changes: 0 additions & 2 deletions tests/PairsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

namespace Pairs\tests;

require_once 'Pairs.php';

use function Pairs\cons;
use function Pairs\car;
use function Pairs\cdr;
Expand Down