Last active
January 12, 2017 12:01
-
-
Save sergiors/a1f4d2dd7e911d12311debbfd57099a6 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 | |
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