関数を扱えるだけでは、モナドを表現するには不十分過ぎる

つまりなぜかいきなり高階型の話です。

これ
関数を扱えることはどのようにプログラミング言語の能力をあげるか

に対する便乗というかツッコミとして。


つい先日もある人がこんなこと https://twitter.com/koropicot/status/365014333413011457 を言っていて*1、「ですよねー」と勝手に納得していたりしましたが。

つまりScalazでよくみるような高階型

trait Monad[F[_]] extends Applicative[F] {
implicit val listMonad = new Monad[List]{

がないと、モナドとして抽象化や共通化ができない、という話です。*2
高階型についてはたとえばこれ

(もりそば)Scalaによる高階型変数 - Higher-kind Generics

とか読んでください。

関数がオブジェクトとして扱えないのは、Java7以前でも「Functionクラス作っておいて、無名クラス量産」すれば、一応それなりにエミュレートできます。もしJavaで高階型をエミュレートするとしたら、どうやるのでしょうか・・・。


それができない点からいうと、Javaが8になってラムダを手にしたとしても「関数型だ! => モナドだ! => 圏論だ!」というのは、ほとんどの人にとっては必要ない流れというかミスリーディングな気がします。つまり、(Scalaでさえ言語の表現力が低くてイライラするのに)本当に圏論を知ったら「高階型さえ直接表現できないJava」に失望してすぐに使いたくなくなるでしょう。


ただ、Java8でOptionalやStreamなどにmapやflatMapなどのモナドの演算のメソッドが入ったことは確かに大きいし、歓迎すべきことです。
逆にいうと、それ以上でもそれ以下でもなく、Javaの言語仕様上、それ以上の高度な抽象化は現実的に考えて厳しいとおもうので、それぞれのクラスにおけるmapやflatMapの使い方が理解できていれば、モナドの一般的な概念自体(ましてや圏論などは)は、ほとんどのJavaプログラマにとってはそれほど必要ないのではないか?という意見です。



がしかし、一応Java8でも高階型をエミュレートする方法はあるようですが

Javaによる高階型変数の実装

果たして、この方法でFunctorやMonadの型を表現するライブラリがもっとでてきて流行ることになるでしょうか・・・?

余談として、そのNagiseさんが紹介しているようなテクニックを使って(?) *3 以前紹介したhighjは

highj・・・Java8による本当の関数型プログラミング?

高階型を一応表現できているようです(?)



追記:

よくわからない自分の言い訳tweetを含んだ、こちらのまとめもどうぞ
togetter 高階型について

*1:たぶんこれは C# に関して

*2: 高階型は、Java にも C# にも F# にも無いが、Scala にはある。でいいんだよね?

*3:よくわかってないので違うテクニックかもしれないが