Scala - monads
6328 ワード
Monads
A monad M is a parametric type M[T] with two operations, flatMap and unit, that have to satisfy some laws.
通常、Monadの
Examples of Monads
以下にScalaのいくつかのMonadsを挙げます. List is a monad with Set is monad with Option is a monad with Generator is a monad with
これらのタイプには同じ
Monads and Map
各monadについて、
Monad Laws
To qualify as a monad, a type has to satisfy three laws: Associativity: Left unit Right unit
Example of Checking Monad Laws
次に、 Checking the Left Unit Lawは、まずLeft Unit Law、すなわち証明 Checking the Right Unit Lawは、Right Unit Law、すなわち Checking the Associative Law最後に、Associative Law、すなわち
Significance of the Laws for For-Expressions Associativity says essentially that one can “inline” nested for expressions: Right unit says: Left unit does not have an analogue for for-expressions.
Another type: Try
次のコースで使用されるタイプは
Scalaでは
Try is used to pass results of computations that can fail with an exception between threads and computers.
すなわち、異常な伝播は、呼び出しスタックではなく、異なるthread、異なるマシン上で伝播することができる.
上記の
このうちパラメータ伝達構文
実際には、
質問ですが、
Indeed the left-hand side will never raise a non-fatal exception whereas the right-hand side will raise any exception thrown by expr or f.
Left unit does not have an analogue for-expressionsの結論によって検証することができ、
Monadという概念は抽象的で、あまり理解しにくいので、今後の授業でMonadの特性を使ってMonadに対する認識を深める必要があります.
map
およびflatMap
の方法を有するデータ構造は一般的である.実際、there’s a name that describes this class of a data structures together with some algebraic laws that they should have.彼らはMonadsと呼ばれています.では、Monadとは何ですか.What is Monad? A monad M is a parametric type M[T] with two operations, flatMap and unit, that have to satisfy some laws.
trait M[T] {
def flatMap[U](f: T => M[U]): M[U]
}
def unit[T](x: T): M[T]
通常、Monadの
flatMap
はbind
と呼ばれる.Examples of Monads
以下にScalaのいくつかのMonadsを挙げます.
unit(x) = List(x)
unit(x) = Set(x)
unit(x) = Some(x)
unit(x) = single(x)
これらのタイプには同じ
flatMap
メソッドが含まれていますが、unit
メソッドはmonadごとに異なる定義が必要です.Monads and Map
各monadについて、
flatMap
およびunit
によってmap
を定義することができる.m map f == m flatMap (x => unit(f(x))) == m flatMap (f andThen unit)
andThen
メソッドは、関数の組合せを表し、f andThen unit
は、まず関数f
を実行し、次いで関数unit
を実行することを表す.Monad Laws
To qualify as a monad, a type has to satisfy three laws:
(m flatMap f) flatMap g == m flatMap (x => f(x) flatMap g)
unit(x) flatMap f == f(x)
m flatMap unit == m
Example of Checking Monad Laws
次に、
Option
がmonad laws
に適合していることを示す例を挙げる.まず、Option
対flatMap
の定義が与えられる.abstract class Option[+T] {
def flatMap[U](f: T => Option[U]): Option[U] = this match {
case Some(x) => f(x)
case None => None
}
}
unit(x) flatMap f == f(x)
を証明し、Option
のUnit
がunit(x) = Some(x)
と定義されているため、証明Some(x) flatMap f == f(x)
である. Some(x) flatMap f ==
Some(x) match {
case Some(x) => f(x)
case None => None
} == f(x)
m flatMap unit == m
、すなわちm flatMap Some == m
を証明する. m flatMap Some ==
m match {
case Some(x) => Some(x)
None => None
} == m
(m flatMap f) flatMap g == m flatMap (x => f(x) flatMap g)
を証明する. (m flatMap f) flatMap g ==
m match { case Some(x) => f(x) case None => None }
match { case Some(y) => g(y) case None => None } ==
m match {
case Some(x) => f(x) match { case Some(y) => g(y) case None => None }
case None => None match { case Some(y) => g(y) case None => None }
} ==
m match {
case Some(x) => f(x) match { case Some(y) => g(y) case None => None }
case None => None
} ==
m match {
case Some(x) => f(x) flatMap g
case None => None
} == m flatMap (x => f(x) flatMap g)
Significance of the Laws for For-Expressions
for (y
for (x
Another type: Try
次のコースで使用されるタイプは
Try
で、彼の定義は以下の通りです.abstract class Try[+T]
case class Success[T](x: T) extends Try[T]
case class Failure(ex: Exception) extends Try[Nothing]
Scalaでは
Nothing
はすべてのタイプのサブタイプであり、通常、異常が発生した場合、何も返されていないことを表すために使用されます.Try
の役割については、次のように説明されています.Try is used to pass results of computations that can fail with an exception between threads and computers.
すなわち、異常な伝播は、呼び出しスタックではなく、異なるthread、異なるマシン上で伝播することができる.
Try
で計算をカプセル化できます.つまり、Try(expr) // gives Success(someValue) or Failure(someException)
上記の
Try
オブジェクトの作成構文をサポートするためには、Try
のObject
タイプを定義し、apply
メソッドを実装する必要がある.apply
メソッドは、()
メソッド名と同様である.次のようになります.object Try {
def apply[T](expr: => T): Try[T] =
try Success(expr)
catch {
case NonFatal(ex) => Failure(ex)
}
}
}
このうちパラメータ伝達構文
expr: => T
はcall by name
を表し、つまりパラメータを伝達する際にevaluate
の評価を先に行わず、try Success(expr)
に入るまでevaluate
を行うことができ、これもapply
内部で異常を捕捉できる原因である.Option
型のように、Try
はfor
式を使用することもできる.例:for {
x
computeX
およびcomputeY
が正常に動作し、結果Success(x)
および結果Success(y)
が得られた場合、式はSuccess(f(x, y))
を返す.上記の2つの演算が1つだけエラーが発生した場合、式はFailure(ex)
を返します.for
式をサポートするためには、Try
型のmap
メソッドおよびflatMap
メソッドを定義する必要がある.次のように定義します.abstract class Try[T] {
def flatMap[U](f: T => Try[U]): Try[U] = this match {
case Success(x) => try f(x) catch { case NonFatal(ex) => Failure(ex) }
case fail: Failure => fail
}
def map[U](f: T => U): Try[U] = this match {
case Success(x) => Try(f(x))
case fail: Failure => fail
}
}
実際には、
map
は、flatMap
によって定義することができる.t map f == t flatMap (x => Try(f(x))) == t flatMap (f andThen Try)
質問ですが、
unit = Try
を定義した後、Try
はmonadではありませんか?答えは:left unit law
、つまりTry(expr) flatMap f != f(expr)
に合わない.どうしてですか.授業で与えられた解釈は:Indeed the left-hand side will never raise a non-fatal exception whereas the right-hand side will raise any exception thrown by expr or f.
Left unit does not have an analogue for-expressionsの結論によって検証することができ、
Try
がleft unit law
違法であってもfor
式を使用することができる.Monadという概念は抽象的で、あまり理解しにくいので、今後の授業でMonadの特性を使ってMonadに対する認識を深める必要があります.