Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

PHPでカリー化?なにそれ美味しいの?

More than 5 years have passed since last update.

食べてみたい?

とりあえず既存の関数をカリー化した関数を返す関数というのを作ってみたわけだが。

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);

いろいろ頑張ってみたが、あまりうれしい感がない、というかコレジャナイ感がただようのはなぜなのか。

計算機科学的にこれがカリー化と呼べるシロモノなのかは正直自信がない。
本場の味を知る人に聞いてみないとわからないところだ。

kumazo
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away