食べてみたい?
とりあえず既存の関数をカリー化した関数を返す関数というのを作ってみたわけだが。
curry.php
<?php
function curry($fn) {
$args = func_get_args();
$fn = array_shift($args);
if (!is_a($fn, 'ReflectionFunction'))
$fn = new ReflectionFunction($fn);
return function() use ($fn, $args) {
$args = array_merge($args, func_get_args());
if (count($args) >= $fn->getNumberOfRequiredParameters())
return $fn->invokeArgs($args);
else
return call_user_func_array(
'curry', array_merge(array($fn), $args));
};
}
使い方
<?php
function hoge($a1, $a2, $a3) {
return $a1 + $a2 + $a3;
}
// 引数を個別渡し
$c0 = curry('hoge');
$c1 = $c0(1);
$c2 = $c1(2);
$ret = $c2(3);
// 複数まとめて
$c0 = curry('hoge');
$c2 = $c0(1, 2);
$ret = $c2(3);
// 最初の引数を決めうち
$c1 = curry('hoge', 1);
$ret = $c1(2, 3);
// 複数引数決めうち
$c2 = curry('hoge', 1, 2);
$ret = $c2(3);
現状、引数の参照渡しには対応していない。(エラーになる)
使用例
<?php
$c = curry('implode');
$csv = $c(',');
$tsv = $c("\t");
$arr = array(1,2,3);
var_dump( $csv($arr)); // string(5) "1,2,3"
var_dump( $tsv($arr)); // string(5) "1 2 3"
<?php
$arr = array(1,2,3);
var_dump( array_map( curry('sprintf', '%04d'), $arr));
/*
array(3) {
[0]=>
string(4) "0001"
[1]=>
string(4) "0002"
[2]=>
string(4) "0003"
}
*/
<?php
$even = curry(function ($m, $v) { return ($v % $m) == 0 ; }, 2);
print_r( array_filter(range(1, 10), $even));
/*
Array
(
[1] => 2
[3] => 4
[5] => 6
[7] => 8
[9] => 10
)*/
<?php
$replace_md_link = curry(
'preg_replace_callback', '/\[(.+?)?\]\((\S+?)(\s+"(.+)")?(\s*?\))/');
$format_link_callback = curry(
'vsprintf', '<a href="%3$s" title="%5$s">%2$s</a>');
$convert_link = curry($replace_md_link, $format_link_callback);
$markdown = '[ほげぶろぐ](http://example.jp "Hoge Blog!")';
var_dump( $convert_link($markdown));
// => string(66) "<a href="http://example.jp" title="Hoge Blog!">ほげぶろぐ</a>"
<?php
$csv = fopen("sample.csv", 'r');
$read_csv = curry('fgetcsv', $csv);
$fields = $read_csv(); // 1行目がフィールド名
$assoc = curry('array_combine', $fields);
$rset = array();
while($values = $read_csv()) {
$rset[] = $assoc($values);
}
fclose($csv);
var_dump($rset);
いろいろ頑張ってみたが、あまりうれしい感がない、というかコレジャナイ感がただようのはなぜなのか。
計算機科学的にこれがカリー化と呼べるシロモノなのかは正直自信がない。
本場の味を知る人に聞いてみないとわからないところだ。