もっと Lambda その7

今日も Java8 がらみのネタです。

今回はちょっといつもと違って私が愛用している高機能な開発環境について少しだけ触れてみたいと思います。

日本でも人気赤丸急上昇中の NetBeans です。

今は Java8 を試すのに開発版を使っています。

注目の Lambda にも徐々にですが対応してます。

以前にも少し紹介したので今回は逆パターンを紹介します。

つまり、Lambda を使わない無名インナークラスを使用する標準的な(?)コードに変換するという試みです。

サンプルは前回のエントリーの JavaCury.java です。

package jp.yucchi.javacurry;

import java.util.function.Function;
import java.util.function.BiFunction;

public class JavaCurry {

    public static void main(String[] args) {

        Function> house = java -> curry -> java + curry;
        System.out.println(house.apply("ジャワ").apply("カレー"));

        BiFunction h = (java, curry) -> java + curry;
        System.out.println(h.apply("ジャワ", "カレー"));
        
        Function>> house2 = java -> curry -> level -> java + curry + level;
        System.out.println(house2.apply("ジャワ").apply("カレー").apply("甘口"));
        
        Function> h2 = java -> (curry, level) -> java +curry + level;
        System.out.println(h2.apply("ジャワ").apply("カレー","辛口"));
    }
}

では、実際にどのように変換されるのかスクリーンショットを撮ってみました。

10 行目の Lambda 式を変換してみます。

2

3

4

5

6

7

8

9

見事に変換されました。さすが NetBeans !

では、もう少し試してみましょう。

10

この Lambda 式は引数の型が省略されてます。

ちまたでは Lambda 式の型省略は企業によっては禁止されるんじゃないかと噂されてます。

それでか、どうかは解りませんが省略された型をコードに追加する機能もあります。

さっそく試してみましょう。

11

12

省略された型がちゃんと追加され表示されてますね。(^_^)

ついでに Lambda 式を複数行で書く場合を試してみます。

13

14

ちゃんと return 文もつくられてますね。

さすがです!

では、無名クラスを使うコードに変換してます。

15

16

17

18

全ての Lambda 式を無名クラスを使うコードに変換したプログラムはこのようになりました。

package jp.yucchi.javacurry;

import java.util.function.Function;
import java.util.function.BiFunction;

public class JavaCurry {

    public static void main(String[] args) {

        Function> house = new Function>() {

            @Override
            public Function apply(String java) {
                return new Function() {

                    @Override
                    public String apply(String curry) {
                        return java + curry;
                    }
                };
            }
        };
        System.out.println(house.apply("ジャワ").apply("カレー"));

        BiFunction h = new BiFunction() {
            @Override
            public String apply(String java, String curry) {
                return java + curry;
            }
        };
        System.out.println(h.apply("ジャワ", "カレー"));

        Function>> house2 = new Function>>() {

            @Override
            public Function> apply(String java) {
                return new Function>() {

                    @Override
                    public Function apply(String curry) {
                        return new Function() {

                            @Override
                            public String apply(String level) {
                                return java + curry + level;
                            }
                        };
                    }
                };
            }
        };
        System.out.println(house2.apply("ジャワ").apply("カレー").apply("甘口"));

        Function> h2 = new Function>() {

            @Override
            public BiFunction apply(String java) {
                return new BiFunction() {

                    @Override
                    public String apply(String curry, String level) {
                        return java + curry + level;
                    }
                };
            }
        };
        System.out.println(h2.apply("ジャワ").apply("カレー", "辛口"));
    }
}

これをみると Lambda 式ってけっこうイケてるかなって思います。

ちなみに Java8 と Java8 対応の NetBeans はまだ開発中なので動作が完全ではありません。

でも、開発版でグリグリやってると開発チームの熱い思いはしっかりと伝わってきます。

きっと Java8 対応の NetBeans もいつも通り素晴らしい出来でリリースされると確信してます。(^_^)

Technorati タグ: ,

もっと Lambda その6

今日はとても感動した記事があったので紹介します。

なんと日本語です!

Java 8を関数型っぽく使うためのおまじない

ちょっとおまじないの部分は私にとっては呪いの呪文のようにもとれました。(>_<。)

この記事の中でカリー化という技法が紹介されてました。

私はこの技法は初めてなので少し調べてみました。

Wikipedia では次のように解説されてました。

カリー化 (currying) とは、計算機科学分野の技法の一つ。複数の引数をとる関数を、引数が「もとの関数の最初の引数」で戻り値が「もとの関数の残りの引数を取り結果を返す関数」であるような関数にすること。

この技法は、クリストファー・ストレイチーにより論理学者ハスケル・カリーに因んで名付けられたが、実際に考案したのは Moses Schönfinkel とゴットロープ・フレーゲである。

f( a, b ) = c という関数 f があるときに、F( a ) = g ただし、g( b ) = c という関数 g が得られる関数 F を定義した場合、F は、f をカリー化したものである。

といことで自分でも試してみたくなりました。

決して疑ってる訳ではありません。新しい未知なるものへのあくなき好奇心からです。

ついでに、甘えと言っていた部分も自分なりに考えてみました。

いつものように未熟なコードですが以下のようにプログラムを組んでみました。


package jp.yucchi.javacurry;

import java.util.function.Function;
import java.util.function.BiFunction;

public class JavaCurry {

    public static void main(String[] args) {

        Function> house = java -> curry -> java + curry;
        System.out.println(house.apply("ジャワ").apply("カレー"));

        BiFunction h = (java, curry) -> java + curry;
        System.out.println(h.apply("ジャワ", "カレー"));
        
        Function>> house2 = java -> curry -> level -> java + curry + level;
        System.out.println(house2.apply("ジャワ").apply("カレー").apply("甘口"));
        
        Function> h2 = java -> (curry, level) -> java +curry + level;
        System.out.println(h2.apply("ジャワ").apply("カレー","辛口"));
    }
}

実行結果は期待通りに次のようになりました。

ジャワカレー
ジャワカレー
ジャワカレー甘口
ジャワカレー辛口

java.util.function.BiFunction を使ってみました。

引数が多くなったときの正しい処理が解らないので適当にしたら期待通りの結果となってしまいました。

間違っている、もしくは正しい方法があるのならご教示いただければ幸いです。

そう言えば、昔 JavaHouse 高木浩光さんのホームページに Java は ジャワカレーとは関係ないという注意書きがあったような気がします。

とてもまじめそうで冗談一つ言わなそうな雰囲気を醸し出していたのでそれがジョークなのか本気なにか聞きたかった覚えがあります。

どうでもいいことだけど

思いっきり思い出した(×_×)

JavaDoc をサラッといっときましょうか。

 

Function

java.​util.​function

@FunctionalInterface
public interface Function<T,R>

Apply a function to the input argument, yielding an appropriate result. A function may variously provide a mapping between types, object instances or keys and values or any other form of transformation upon the input.

パラメータ:

T – the type of the input to the apply operation
R – the type of the result of the apply operation

日付:

1.8

 

apply()

java.​util.​function.​Function

public R apply(T t)

Compute the result of applying the function to the input argument

パラメータ:

t – the input object

戻り値:

the function result

 

BiFunction

java.​util.​function

@FunctionalInterface
public interface BiFunction<T,U,R>

Apply a function to the input arguments, yielding an appropriate result. This is the two-arity specialization of Function. A function may variously provide a mapping between types, object instances or keys and values or any other form of transformation upon the input.

パラメータ:

T – the type of the first argument to the apply operation
U – the type of the second argument to the apply operation
R – the type of results returned by the apply operation

日付:

1.8

 

それでは、お約束の時間です。

この「もっと Lambda 」シリーズは、インターネット上で得た情報を元にそれを少し変更しているだけです。

よって私の推測で解釈された内容が部分的にありますので間違いがあると思います。

Java8 もまだ build86 を使用していますので API の変更により記述方法が変わるかもしれません。

早く正式リリースされて日本語でこの超便利で素敵な新機能を勉強したい今日この頃です。

 

Hatena タグ: