Functionで遊ぶJava

この記事は[Go言語で高階関数を書いて遊んでみた](https://qiita.com/shiki_tak/items/54ee5b84cd98a4349efe)でも登場した某友人の記事[クロージャで遊ぶSwift](https://qiita.com/_makanai/items/ca313c8e117da78154fa)に対するオマージュです。
（元記事にもある通り）楽しい以外の何でもないので、有益な実装を求めていた方は、ブラウザバック推奨です。

（注）深夜テンションで書いてるので、変な箇所があるかもしれませんがご了承くださいm(_ _)m

# 本題
hoge1 ~ 4は、返却値がFunctionのため、さらに引数を渡すことができる

```java
// Integerをとり、Integerを返す
Function<Integer, Integer> hoge1 = value -> value;
hoge1.apply(1); // return 1
```

```java
// Integerをとり、IntegerをとりIntegerを返す関数を返す
Function<Integer, Function<Integer, Integer>> hoge2 = value -> (a -> value + a);
hoge2.apply(1).apply(2);    // return 3
```

```java
/// Integerをとり、IntegerをとりIntegerをとりIntegerを返す関数を返す
Function<Integer, Function<Integer, Function<Integer, Integer>>> hoge3 = value -> (a -> (b -> value + a + b));
hoge3.apply(1).apply(2).apply(4);   // return 7
```

```java
// Integerをとり、IntegerをとりIntegerをとりIntegerをとりIntegerを返す関数を返す
Function<Integer, Function<Integer, Function<Integer, Function<Integer, Integer>>>> hoge4 = value -> (a -> (b -> (c -> value + a + b + c)));
hoge4.apply(1).apply(2).apply(4).apply(8);  // return 15
```
---
hoge5 ~ 7 は、引数がクロージャのため、事前に処理を渡しておく必要がある
（hoge5 ~ 7 は、引数が関数のため、hoge1 ~ 4 の返却値を使いました）

```java
// IntegerをとりIntegerを返す関数をとり、IntegerをとりIntegerをとりIntegerをとりIntegerを返す関数を返す
Function<Function<Integer, Integer>, Function<Integer, Function<Integer, Function<Integer, Integer>>>> hoge5 = hoge -> (a -> (b -> (c -> hoge.apply(a + b + c))));

hoge5.apply(hoge1).apply(1).apply(2).apply(4);  // return 7
hoge5.apply(hoge2.apply(1)).apply(2).apply(4).apply(8); // return 15
hoge5.apply(hoge3.apply(1).apply(2)).apply(4).apply(8).apply(16);   // return 31
hoge5.apply(hoge4.apply(1).apply(2).apply(4)).apply(8).apply(16).apply(32); // return 63
```

```java
// IntegerをとりIntegerをとりIntegerを返す関数をとり、IntegerをとりIntegerをとりIntegerをとりIntegerを返す関数を返す
Function<Function<Integer, Function<Integer, Integer>>, Function<Integer, Function<Integer, Function<Integer, Integer>>>> hoge6 = hoge -> (a -> (b -> (c -> hoge.apply(a).apply(b + c))));

hoge6.apply(hoge2).apply(1).apply(2).apply(4);  // return 7
hoge6.apply(hoge3.apply(1)).apply(2).apply(4).apply(8); // return 15
hoge6.apply(hoge4.apply(1).apply(2)).apply(4).apply(8).apply(16);   // return 31
```

```java
// IntegerをとりIntegerをとりIntegerをとりIntegerを返す関数をとり、IntegerをとりIntegerをとりIntegerをとりIntegerを返す関数を返す
Function<Function<Integer, Function<Integer, Function<Integer, Integer>>>, Function<Integer, Function<Integer, Function<Integer, Integer>>>> hoge7 = hoge -> (a -> (b -> (c -> hoge.apply(a).apply(b).apply(c))));

hoge7.apply(hoge3).apply(1).apply(2).apply(4);  // return 7
hoge7.apply(hoge4.apply(1)).apply(2).apply(4).apply(8); // return 15
```

---

返却値である関数をそのまま持つことももちろんできる
数値を渡しているが、実際に計算は行われていない

```java
hoge7.apply(hoge3); // return Function
hoge7.apply(hoge3).apply(1);    // return Function
hoge7.apply(hoge3).apply(1).apply(2);   // return Function
```

ループを回して、全部足す...
Java8以前ではfor文を使っていた計算もご覧の通り！
そろそろ眠くなってきた...w

```java
int sum = IntStream.rangeClosed(1, 100).sum();    // return 5050
```

---

TとTをとりTを返すクロージャをとり、TをとりTをとりTを返すクロージャを返す（また明日でいいや...ww）

---

ループを回して最大値を得る（stream処理でなんとかしよう...）

# 最後に
すべてきちんと読んだ方、お疲れ様でした。（最後は力尽きたのでまた次回にします...）
実際のプロダクトには上記のような他人が読みづらいクソコードは埋め込まないように注意しましょう。

関数型プログラミングって慣れないとツライですが、わかるようになってくると楽しいです。
とりあえず、Javaによる関数型プログラミングをやって、すごいH本も読もうと思います。

P.S
Javaのラムダ式ってどこで改行するのがベストなんでしょうか...(･･?)