読者です 読者をやめる 読者になる 読者になる

Fight the Future




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

The First Monad Law: Identity(第一のモナド則:同一性)

The first and simplest of the monad laws is the monad identity law


  • M1. m flatMap unit ≡ m // or equivalently
  • M1a. m flatMap {x => unit(x)} ≡ m

Where the connector law connected 3 concepts, this law focuses on the relationship between 2 of them. One way of reading this law is that, in a sense, flatMap undoes whatever unit does. Again the reminder that the object that results on the left may actually be a bit different internally as long as it behaves the same as "m."


Using this and the connection law, we can derive the functor identity law


  • m flatMap {x => unit(x)} ≡ m // M1a
  • m flatMap {x => unit(identity(x))}≡ m // identity
  • F1b. m map {x => identity(x)} ≡ m // by FM1

ファンクターの第1法則は「m map identity ≡ m」。map {x => identity(x)} と map identity は等価。

The same derivation works in reverse, too. Expressed in "for" notation, the monad identity law is pretty straight forward


  • M1c. for (x <- m; y <- unit(x)) yield y ≡ m

The Second Monad Law: Unit(モナドの第2法則:Unit)

Monads have a sort of reverse to the monad identity law.


  • M2. unit(x) flatMap f ≡ f(x) // or equivalently
  • M2a. unit(x) flatMap {y => f(y)} ≡ f(x)

The law is basically saying that unit(x) must somehow preserve x in order to be able to figure out f(x) if f is handed to it. It's in precisely this sense that it's safe to say that any monad is a type of container (but that doesn't mean a monad is a collection!).


In "for" notation, the unit law becomes


  • M2b. for (y <- unit(x); result <- f(y)) yield result ≡ f(x)

This law has another implication for unit and how it relates to map


  1. unit(x) map f ≡ unit(x) map f // no, really, it does!
  2. unit(x) map f ≡ unit(x) flatMap {y => unit(f(y))} // by FM1
  3. M2c. unit(x) map f ≡ unit(f(x)) // by M2a

In other words, if we create a monad instance from a single argument x and then map it using f we should get the same result as if we had created the monad instance from the result of applying f to x. In for notation


  • M2d. for (y <- unit(x)) yield f(y) ≡ unit(f(x))

The Third Monad Law: Composition(モナド第3法則:コンポジション)

The composition law for monads is a rule for how a series of flatMaps work together.


  • M3. m flatMap g flatMap f ≡ m flatMap {x => g(x) flatMap f} // or equivalently
  • M3a. m flatMap {x => g(x)} flatMap {y => f(y)} ≡ m flatMap {x => g(x) flatMap {y => f(y) }}

It's the most complicated of all our laws and takes some time to appreciate. On the left side we start with a monad, m, flatMap it with g. Then that result is flatMapped with f. On the right side, we create an anonymous function that applies g to its argument and then flatMaps that result with f. Finally m is flatMapped with the anonymous function. Both have same result.


In "for" notation, the composition law will send you fleeing in terror, so I recommend skipping it


  • M3b. for (a <- m;b <- g(a);result <- f(b)) yield result ≡ for(a <- m; result <- for(b < g(a); temp <- f(b)) yield temp) yield result

From this law, we can derive the functor composition law. Which is to say breaking the monad composition law also breaks the (simpler) functor composition. The proof involves throwing several monad laws at the problem and it's not for the faint of heart


  1. m map g map f ≡ m map g map f // I'm pretty sure
  2. m map g map f ≡ m flatMap {x => unit(g(x))} flatMap {y => unit(f(y))} // by FM1, twice
  3. m map g map f ≡ m flatMap {x => unit(g(x)) flatMap {y => unit(f(y))}} // by M3a
  4. m map g map f ≡ m flatMap {x => unit(g(x)) map {y => f(y)}} // by FM1a
  5. m map g map f ≡ m flatMap {x => unit(f(g(x))} // by M2c
  6. F2. m map g map f ≡ m map {x => f(g(x))} // by FM1a

Total Loser Zeros(完全な敗者はいない)

List has Nil (the empty list) and Option has None. Nil and None seem to have a certain similarity: they both represent a kind of emptiness. Formally they're called monadic zeros.


A monad may have many zeros. For instance, imagine an Option-like monad called Result. A Result can either be a Success(value) or a Failure(msg). The Failure constructor takes a string indicating why the failure occurred. Every different failure object is a different zero for Result.

モナドは多くのゼロを持っているかもしれません。例えばResultと呼ぶOptionのようなモナド想像してみてください。ResultはSuccess(value) かFailure(msg)のどちらかです。Failureのコンストラクタはなぜ失敗が起こったかを示す文字列を引数に取ります。すべての異なるfailureオブジェクトはResultにとって異なるゼロとなります。

A monad may have no zeros. While all collection monads will have zeros (empty collections) other kinds of monads may or may not depending on whether they have a concept of emptiness or failure that can follow the zero laws.


The First Zero Law: Identity(第1のゼロの法則:同一性)

If mzero is a monadic zero then for any f it makes sense that


  • MZ1. mzero flatMap f ≡ mzero

Translated into Texan: if t'ain't nothin' to start with then t'ain't gonna be nothin' after neither.


This law allows us to derive another zero law


  1. mzero map f ≡ mzero map f // identity
  2. mzero map f ≡ mzero flatMap {x => unit(f(x)) // by FM1
  3. MZ1b. mzero map f ≡ mzero // by MZ1

So taking a zero and mapping with any function also results in a zero. This law makes clear that a zero is different from, say, unit(null) or some other construction that may appear empty but isn't quite empty enough. To see why look at this


  • unit(null) map {x => "Nope, not empty enough to be a zero"} ≡ unit("Nope, not empty enough to be a zero")