Scala 如果unit=Success,是否尝试单子?

Scala 如果unit=Success,是否尝试单子?,scala,monads,Scala,Monads,对于unit=Try,Try不是单子,因为左单位法则失败 Try(expr) flatMap f != f(expr) 但问题变成了什么:如果unit=Success,它是不是Trymonad 在这种情况下: Success(expr) flatMap f == f(expr) 所以它是单子 我的理解正确吗?基本上正确。通常单子是用纯函数语言定义的,其中equality==具有equality的一般属性,即我们可以用equals替换equals。如果您在Scala的这样一个子集内

对于
unit=Try
Try
不是单子,因为左单位法则失败

 Try(expr) flatMap f  !=  f(expr)
但问题变成了什么:如果
unit=Success
,它是不是
Try
monad

在这种情况下:

 Success(expr) flatMap f  ==  f(expr)
所以它是单子


我的理解正确吗?

基本上正确。通常单子是用纯函数语言定义的,其中equality==具有equality的一般属性,即我们可以用equals替换equals。如果您在Scala的这样一个子集内,那么您确实可以给出表示可能异常计算的参数类型的自然定义。这里有一个例子。该示例实际上碰巧在Scala()的Leon验证系统中进行了机械验证


在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

的主要功能。这通常是为
Try
编写单元的方式,可以说它仍然违反了组合规则。这些讨论都很有说服力,但我个人认为它们并没有什么价值。我认为这个案子完全没用。不能使用Try来抛出异常。Scala的一个弱点就是可以编写这样的代码。如果您仍然不确信,那么将这一行放入一些f:
Thread.currentThread().getStackTrace.find({uu.getMethodName.contains(“flatMap”))).foreach{{{u=>抛出新的RuntimeException(“no monad no cry”)}
,您实际上可以杀死scala中编写的任何monad。
Success(throw new Exception) flatMap f == f(throw new Exception) // holds
Success(s) flatMap (x => throw new Exception) == Failure(new Exception) // does not hold