Fight the Future

Java言語とJVM、そしてJavaエコシステム全般にまつわること

モナドについて調べていく(11)

One Div Zero: Monads are Elephants Part 1の翻訳続き。

Monads Can Be Built In Different Ways(モナドは構築する方法がいくつもある)


So we've seen how the flatMap method can be built using map.

mapを使ってflatMapメソッドを構築する方法を見てきました。


It's possible to go the other way: start with flatMap and create map based on it.

逆も可能です。flatMapをベースにmapを作成することもできます。


In order to do so we need one more concept. In most papers on monads the concept is called "unit," in Haskell it's called "return."

そうするためにはもう1つ概念が必要です。モナドに関するほとんどの論文で、その概念は「unit」と呼んでいます。Haskellでは「return」と呼びます。


Scala is an object oriented language so the same concept might be called a single argument "constructor" or "factory."

Scalaオブジェクト指向言語なので同じ概念は単一引数の「コンストラクタ」または「ファクトリ」と呼ぶかもしれません。


Basically, unit takes one value of type A and turns it into a monad of type M[A]. For List, unit(x) == List(x) and for Option, unit(x) == Some(x).

基本的にunitはA型の値を1つ引数に取り、M[A]型のモナドに変換します。リストであればunit(x) == List(x)となり、Optionであればunit(x) == Some(x)となります。


Scala does not require a separate "unit" function or method, and whether you write it or not is a matter of taste. In writing this version of map I'll explicitly write "unit" just to show how it fits into things.

Scalaは個別の「unit」関数またはメソッドを必要としません。書く書かないどちらでもいい。
このバージョンのmapを記述するにあたって明確に「unit」を書くことにします。
それがきちんとフィットすることを示すだけのためです。

class M[A](value: A) {
  private def unit[B] (value : B) = new M(value)
  def map[B](f: A => B) : M[B] = flatMap {x => unit(f(x))}
  def flatMap[B](f: A => M[B]) : M[B] = ...
}

In this version flatMap has to be built without reference to map or flatten - it will have to do both in one go.

このバージョンのflatMapはmapやflattenへの参照なしに構築する必要があります。両方とも一気にしなければなりません。


The interesting bit is map. It takes the function passed in (f) and turns it into a new function that is appropriate for flatMap.

mapは少しおもしろいです。(f)に渡された関数を引数に取り、flatMapに適した新しい関数を適用します。


The new function looks like {x => unit(f(x))} meaning that first f is applied to x, then unit is applied to the result.

新しい関数は{x => unit(f(x))}のようですが、意味はこうです。まずxに関数fを適用してその結果にunitを適用します。