Knowledge Base

お知らせや身辺のことを綴っています。
目次
PHPでカリー化を使ってみたよ

PHPでカリー化を使ってみたよ

2つの値を記号でつないでくれる関数を作った

変数 x と変数 y を記号でつないで1つの文字列として出力してくれる関数を作りたい。もちろん、単純に2つの値を記号でつなぐだけなら2個以上の引数を用意してこういう書き方もできる。

fn (string $x, string $y): string => "$x ~ $y"

しかし、カリー化を勉強したい

しかし、今回はその関数の取る引数を分割し、関数の呼び出しの連続にするような形にして、それぞれの関数が引数を1つしか取らないように作り変えてみる。いわゆるカリー化っぽいもの。

ちなみにPHPのリファレンスではカリー化などという仰々しい単語は使わずに、アロー関数をネストするユースケースにだけ言及している。

https://www.php.net/manual/ja/functions.arrow.php#example-186

そうしてできたのがこれ。上のアロー関数を使用しないパタンは書いていて非常にダルいので下のアロー関数を使う方法がおすすめ。

$format_tilde = function (string $x) {
    # こんなに関数が長くなるようなら関数宣言を使った方が良いw
    return function (string $y) use ($x): string { 
        return "$x ~ $y";
    };
};
# おすすめ
$format_slash = fn (string $x) => fn (string $y): string => "$x // $y";

とりあえず使ってみる。

これは、アーティスト名とそのアーティストが作ったトラック名を先ほどの$format_tildeに通すことで、それぞれをつないだ文字列を返す手続きである。複数の値をまとめて処理したかったので、配列としてまとめてarray_map()の中で呼び出されるコールバック関数の中に組み込んで使ってみた。カリー化関数を使うときは、呼び出し時にカッコを繋げて呼び出しが連続するように書く。

$tracks_with_artists = array_map(
    fn ($x, $y) => $format_tilde($x)($y),
    ['遅梅雨', "Petrichor's session", 'ファフロツキーズ', '酸紅涙', '雨と虹の傘', 'Me with Seagulls'],
    ['1223', 'kre4tive', 'おさかな', 'さたん', '運命のドツボ', 'Yokkin']
);
print_r($tracks_with_artists);

出力

Array
(
    [0] => 遅梅雨 ~ 1223
    [1] => Petrichor's session ~ kre4tive
    [2] => ファフロツキーズ ~ おさかな
    [3] => 酸紅涙 ~ さたん
    [4] => 雨と虹の傘 ~ 運命のドツボ
    [5] => Me with Seagulls ~ Yokkin
)

他のケースでも使ってみる。今度は、$format_tildeではなく$format_slashを呼び出してみた。

$group_name = 'sanctunes';
$group_name_added = array_map(
    fn ($x) => $format_slash($group_name)($x),
    $tracks_with_artists
);

出力

Array
(
    [0] => sanctunes // 遅梅雨 ~ 1223
    [1] => sanctunes // Petrichor's session ~ kre4tive
    [2] => sanctunes // ファフロツキーズ ~ おさかな
    [3] => sanctunes // 酸紅涙 ~ さたん
    [4] => sanctunes // 雨と虹の傘 ~ 運命のドツボ
    [5] => sanctunes // Me with Seagulls ~ Yokkin
)

動作確認については終了。

不十分な数の引数を与えてみる

気になったので、未完成状態の関数の様子を、print_rに突っ込んで見てみた。

無名関数は、Closureオブジェクトを生成するので、型がClosure Objectになっているのはわかる。これらの無名関数がとる引数は、それぞれ連想配列として渡され、前もって引数で与えられている値はstaticというキーを持った連想配列として、まだ不定の部分はparameterというキーを持った連想配列として渡されるようだ。

parameterの部分は、値が必要である(required)状態を示している。

$format_tilde = fn (string $x) => fn (string $y): string => "$x ~ $y";
print_r($format_tilde('遅梅雨'));

出力

Closure Object
(
    [static] => Array
        (
            [x] => 遅梅雨
        )

    [parameter] => Array
        (
            [$y] => <required>
        )

)

おわり

PHPのアロー関数、JSの成り下がりみたいでおもしろいし、普通の関数同様に型を書けるのもありがたい。

前の記事

AtCoder Beginners Contest 303 を PHP で解く

次の記事

中華フォントはどうにかならないか?→ならない

コメント

0

コメントはありません。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

関連投稿

プログラミング
「subprocessのPopenを使ってプロセス間通信させる」のサムネイル画像

subprocessのPopenを使ってプロセス間通信させる

PythonのsubprocessモジュールのPopenを使って、アプリケーションをパイプでつないでみました。 続きを読む

プログラミング
「ABC329 を Python で解く (AからD問題まで)」のサムネイル画像

ABC329 を Python で解く (AからD問題まで)

AtCoderで解いた問題の振り返りを行うための自分用のメモです。 続きを読む

プログラミング
「AtCoder Beginners Contest 303 を PHP で解く」のサムネイル画像

AtCoder Beginners Contest 303 を PHP で解く

AtCoderで解いた問題の振り返りを行うための自分用のメモです。 続きを読む