如果 unit = Success,`Try` 是 monad 吗?
Is `Try` a monad if unit = Success?
对于unit = Try
,Try
不是单子,因为左单位律失效。
Try(expr) flatMap f != f(expr)
但是问题变成了:Try
是 monad,如果 unit = Success
?
在这种情况下:
Success(expr) flatMap f == f(expr)
所以它是一个monad。
我的理解正确吗?
基本上,是的。通常 monad 是用纯函数式语言定义的,其中 equality == 具有 equality 的常见属性,即我们可以用 equals 代替 equals。如果您属于 Scala 的此类子集,那么您确实可以给出代表可能异常计算的参数类型的自然定义。这是一个例子。该示例实际上恰好在Scala的Leon验证系统中进行了机械验证(http://leon.epfl.ch)。
import leon.lang._
object TryMonad {
// Exception monad similar to Option monad, with an error message id for None
sealed abstract class M[T] {
def bind[S](f: T => M[S]): M[S] = {
this match {
case Exc(str) => Exc[S](str)
case Success(t) => f(t)
}
}
}
case class Exc[T](err: BigInt) extends M[T]
case class Success[T](t: T) extends M[T]
// unit is success
def unit[T](t:T) = Success(t)
// all laws hold
def leftIdentity[T,S](t: T, f: T => M[S]): Boolean = {
unit(t).bind(f) == f(t)
}.holds
def rightIdentity[T](m: M[T]): Boolean = {
m.bind(unit(_)) == m
}.holds
def associativity[T,S,R](m: M[T], f: T => M[S], g: S => M[R]): Boolean = {
m.bind(f).bind(g) == m.bind((t:T) => f(t).bind(g))
}.holds
}
在 coursera 论坛上得到了 Alexey 帮助的回答:
当unit = Success
时,对于左单位律:
Success(throw new Exception) flatMap f == f(throw new Exception) // holds
Success(s) flatMap (x => throw new Exception) == Failure(new Exception) // does not hold
其实又输了,当然除非你重新定义flatMap重新抛出异常,从而失去Try
的主要功能
对于unit = Try
,Try
不是单子,因为左单位律失效。
Try(expr) flatMap f != f(expr)
但是问题变成了:Try
是 monad,如果 unit = Success
?
在这种情况下:
Success(expr) flatMap f == f(expr)
所以它是一个monad。
我的理解正确吗?
基本上,是的。通常 monad 是用纯函数式语言定义的,其中 equality == 具有 equality 的常见属性,即我们可以用 equals 代替 equals。如果您属于 Scala 的此类子集,那么您确实可以给出代表可能异常计算的参数类型的自然定义。这是一个例子。该示例实际上恰好在Scala的Leon验证系统中进行了机械验证(http://leon.epfl.ch)。
import leon.lang._
object TryMonad {
// Exception monad similar to Option monad, with an error message id for None
sealed abstract class M[T] {
def bind[S](f: T => M[S]): M[S] = {
this match {
case Exc(str) => Exc[S](str)
case Success(t) => f(t)
}
}
}
case class Exc[T](err: BigInt) extends M[T]
case class Success[T](t: T) extends M[T]
// unit is success
def unit[T](t:T) = Success(t)
// all laws hold
def leftIdentity[T,S](t: T, f: T => M[S]): Boolean = {
unit(t).bind(f) == f(t)
}.holds
def rightIdentity[T](m: M[T]): Boolean = {
m.bind(unit(_)) == m
}.holds
def associativity[T,S,R](m: M[T], f: T => M[S], g: S => M[R]): Boolean = {
m.bind(f).bind(g) == m.bind((t:T) => f(t).bind(g))
}.holds
}
在 coursera 论坛上得到了 Alexey 帮助的回答:
当unit = Success
时,对于左单位律:
Success(throw new Exception) flatMap f == f(throw new Exception) // holds
Success(s) flatMap (x => throw new Exception) == Failure(new Exception) // does not hold
其实又输了,当然除非你重新定义flatMap重新抛出异常,从而失去Try