Skip to content

Instantly share code, notes, and snippets.

@sergiors
Last active January 12, 2017 12:01
Show Gist options
  • Save sergiors/a1f4d2dd7e911d12311debbfd57099a6 to your computer and use it in GitHub Desktop.
Save sergiors/a1f4d2dd7e911d12311debbfd57099a6 to your computer and use it in GitHub Desktop.
<?php
declare(strict_types = 1);
function id($x)
{
return $x;
}
function anyPass(array $preds)
{
return function ($x) use ($preds) {
return array_reduce($preds, function ($prev, callable $pred) use ($x) {
return true === $prev
? $prev
: $pred($x);
}, false);
};
}
function isEmpty($x)
{
return anyPass([
'is_null',
equals(''),
equals(0),
equals(0.0),
equals('0'),
equals([]),
equals(false),
])($x);
}
function ifElse(callable $pred)
{
return function (callable $succfn) use ($pred) {
return function (callable $failfn) use ($pred, $succfn) {
return function ($x = null) use ($pred, $succfn, $failfn) {
return $pred($x)
? $succfn($x)
: $failfn($x);
};
};
};
}
function equals($x)
{
return function ($y) use ($x) {
return $y === $x;
};
}
function always($x)
{
return function () use ($x) {
return $x;
};
}
function has($x)
{
return function (array $xss) use ($x) {
return isset($xss[$x]);
};
}
function cond(array $pairs)
{
return function ($x) use ($pairs) {
$pair = head($pairs);
if (!isset($pair[1])) {
throw new \InvalidArgumentException();
}
$lazyfn = function ($x) use ($pairs) {
return cond(tail($pairs))($x);
};
return ifElse($pair[0])
($pair[1])
($lazyfn)
($x);
};
}
function head(array $xss)
{
if ([] === $xss) {
throw new \InvalidArgumentException();
}
return array_values(array_slice($xss, 0, 1))[0];
}
function tail(array $xss) {
return array_slice($xss, 1);
}
function get(array $xss)
{
return function ($x, $notfound = false) use ($xss) {
return $xss[$x] ?? $notfound;
};
}
function getIn(array $xss)
{
return function (array $ks, $notfound = false) use ($xss) {
$lazyfn = function (array $ks) use ($xss, $notfound) {
$xs = get($xss)(head($ks), $notfound);
return is_array($xs)
? getIn($xs)(tail($ks), $notfound)
: $xs;
};
return cond([
[has(0), $lazyfn],
[always(true), always($notfound)]
])($ks);
};
}
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
assert(head($numbers) === 1);
assert(tail($numbers) === [2, 3, 4, 5, 6, 7, 8, 9, 0]);
$user = [
'username' => 'sally',
'profile' => [
'name' => 'Sally Clojurian',
'address' => [
'city' => 'Austin',
'state' => 'TX'
]
]
];
$xuser = get($user);
assert($xuser('name', null) === null);
assert($xuser('username') === 'sally');
$yuser = getIn($user);
assert($yuser([], null) === null);
assert($yuser(['profile', 'name']) === 'Sally Clojurian');
assert($yuser(['profile', 'address', 'city']) === 'Austin');
$xcond = cond([
[equals(0), always('water freezes at 0°C')],
[equals(100), always('water boils at 100°C')],
[always(true), function ($temp) {
return 'nothing special happens at '.$temp.'°C';
}]
]);
assert($xcond(0) === 'water freezes at 0°C');
assert($xcond(100) === 'water boils at 100°C');
assert($xcond(50) === 'nothing special happens at 50°C');
$xanyPass = anyPass([has('telephone'), has('name')]);
$yanyPass = anyPass([has('username')]);
assert($xanyPass($user) === false);
assert($yanyPass($user) === true);
assert(isEmpty('') === true);
assert(isEmpty(null) === true);
assert(isEmpty(0) === true);
assert(isEmpty(0.1) === false);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment