Last active
August 29, 2015 14:19
-
-
Save n1215/0b4bc8a973b111c483f4 to your computer and use it in GitHub Desktop.
PHPでFizzBuzz 関数合成風味
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 | |
namespace Compose; | |
/** | |
* 関数を合成 | |
* pipe(f, g, h) なら h(g(f)) | |
* | |
* @return callable | |
*/ | |
function pipe() | |
{ | |
$callables = func_get_args(); | |
if(count($callables) < 2) { | |
throw new \InvalidArgumentException('\Compose\pipe() expects at least 2 callables'); | |
} | |
return array_reduce($callables, function ($carry, callable $func) { | |
if ($carry === null) { | |
return function () use ($func) { | |
return call_user_func_array($func, func_get_args()); | |
}; | |
} | |
return function () use ($carry, $func) { | |
return call_user_func($func, call_user_func_array($carry, func_get_args())); | |
}; | |
}); | |
} | |
/** | |
* 配列用の関数に変換 | |
* | |
* @param callable $func 元の関数 | |
* @return callable | |
*/ | |
function map(callable $func) | |
{ | |
return function(array $arr) use ($func) { | |
return array_map($func, $arr); | |
}; | |
} | |
/** | |
* pipe()のテスト | |
*/ | |
function testPipe() | |
{ | |
$plus = function($x, $y) { return $x + $y;}; | |
$multiply = function($x, $y, $z) { return $x * $y * $z;}; | |
$double = function($x) { return 2 * $x;}; | |
$triple = function($x) { return 3 * $x;}; | |
$func1 = pipe($double, $triple); | |
assert($func1(2) === 12); | |
$func2 = pipe($plus, $double); | |
assert($func2(10, 3) === 26); | |
$func3 = pipe($multiply, $triple); | |
assert($func3(2, 3, 4) === 72); | |
$func4 = pipe($plus, $double, $triple); | |
assert($func4(100, 11) === 666); | |
} | |
/** | |
* map()のテスト | |
*/ | |
function testMap() | |
{ | |
$func = map(function($x) { return $x * 2;}); | |
assert($func(array(1, 2, 3)) === array(2, 4, 6)); | |
} | |
testPipe(); | |
testMap(); |
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 | |
namespace FizzBuzz; | |
require_once './Compose.php'; | |
function main() | |
{ | |
$displayAsHtml = false; // 表示の切り替え用 | |
$decorate = $displayAsHtml ? 'FizzBuzz\decorateHtml' : 'FizzBuzz\decorate'; | |
$fizzBuzz = \Compose\pipe( | |
'\range', // 入力となる整数配列を生成 | |
\Compose\map('FizzBuzz\evaluate'), // 配列の要素それぞれをFizzBuzzのルールで評価 | |
$decorate, // 配列を表示用の文字列に変換 | |
function($str) { echo $str; } // 文字列を出力 | |
); | |
$fizzBuzz(1, 30); | |
} | |
function evaluate($num) | |
{ | |
return array_first( | |
array(15 => 'FizzBuzz', 5 => 'Buzz', 3 => 'Fizz'), | |
function ($divisor, $str) use ($num) { return $num % $divisor === 0; }, | |
strval($num) | |
); | |
} | |
function decorate($array) | |
{ | |
return \join(' ', $array) . PHP_EOL; | |
} | |
function decorateHtml(array $arr) | |
{ | |
return '<ul>' . PHP_EOL ."\t<li>" | |
. \join('</li>' . PHP_EOL . "\t<li>", $arr) | |
. '</li>' . PHP_EOL . '</ul>' | |
. PHP_EOL; | |
} | |
function array_first($array, $callback, $default) | |
{ | |
foreach($array as $key => $value) | |
{ | |
if (call_user_func($callback, $key, $value)) { | |
return $value; | |
} | |
} | |
return $default; | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment