Fight the Future



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.


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


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."


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


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.


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.


The interesting bit is map. It takes the function passed in (f) and turns it into a new function that is appropriate for 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を適用します。