こういうことができます
scala> def kakezan(x: Int, y: Int) = x * y kakezan: (x: Int, y: Int)Int scala> kakezan(3, 7) res1: Int = 21 scala> def curried_kakezan(x: Int)(y: Int) = x * y curried_kakezan: (x: Int)(y: Int)Int
使い方は、というとcurryingを作った後で使い方はまず最初の第1パラメーターを代入して関数を呼び出しますと
以下のようなエラーが出てしまいます
どうやらそのカラーリングの関数の後あとと言うか関数はどれぐらいの引数を受け取るのかというような情報を与えてやらないとうまく動作しない
これは個人的には分かりづらくて面白くありませんがそういう仕様です
このアンダースコアの書き方は例えば二つ目の引数を受け取るのであればもう一つかっこを加えてその中をアンダースコアで埋めます
scala> curried_kakezan(3) ^ error: missing argument list for method curried_kakezan Unapplied methods are only converted to functions when a function type is expected. You can make this conversion explicit by writing `curried_kakezan _` or `curried_kakezan(_)(_)` instead of `curried_kakezan`. scala> curried_kakezan(3)(_) res3: Int => Int = $$Lambda$7809/0x0000000802ad6840@2b844ce scala> val ck = curried_kakezan(3)(_) ck: Int => Int = $$Lambda$7810/0x0000000802ad8840@6332444b scala> ck(7) res4: Int = 21 scala> ck(8) res5: Int = 24
なにが
何が嬉しいかと言うと関数を関数元号というぐらいでこれが本領発揮ということで関数を持ち運べると
関数を途中の製造段階で色々持ち運んでそれぞれの加工先でさらに好きに改造してくれよ
例えるならば冷凍食品冷凍食品は工場であらかじめほとんどの工程を終わらせて後はレンジでチンするだけというような状態で家庭に届きます
あなたのすることはその冷凍食品をレンジでチンし更にお好みの味付けをするということです
言うなれば工場であらかじめ作られる過程が最初のカロリーイングでその後の工程は各ユーザーでお好みでやりたいことをできる
ユーザーはその冷凍食品がどのように作られたかというような工程を一切する知る必要がありません
そのある意味ブラックボックス化してそれを移動させられる他の人に委ねられるというようなことができるというのがクーリングの特徴であると私は理解しています
さて今日はパスタの冷凍食品をたらこパスタの冷凍食品を少し醤油を垂らして食べてみようかな
内部的には以下のように展開されます。
ちょっと、先程の途中までの呼び出しの補足もありまして、
別の方法もあり格好つけずに単純にアンダースコアをつけるだけです
こうするとその後このカリウムが何十になっていても対応できるので便利です、が見た目は大変分かりづらいです
あらためまして、内部的には
scala> curried_kakezan(3)_ res6: Int => Int = $$Lambda$7811/0x0000000802ad5840@6933b02 scala> scala> def curried_kakezan_impl(x: Int): (Int) => Int = { | def kakezan_inner(y: Int): Int = { | x * y | } | return kakezan_inner | } curried_kakezan_impl: (x: Int)Int => Int scala> curried_kakezan_impl(3) res7: Int => Int = $$Lambda$7816/0x0000000802af8840@195cb214 scala> curried_kakezan_impl(3)(9) res8: Int = 27
最後に
このcurryingはFutureというクラスでも使われておりそのフューチャーを勉強するために今回私は改めてcurryingを学びなおしましたというわけです
以上です