Violation of the left identity law for Future monads in scalaz

走远了吗. 提交于 2019-12-09 16:55:35

问题


Suppose I define an instance of the Monad typeclass for Future:

val futureMonad = new Monad[Future] {
  override def point[A](a: ⇒ A): Future[A] =
    Future(a)

  override def bind[A, B](fa: Future[A])(f: A => Future[B]): Future[B] =
    fa flatMap f
}

Strictly speaking, this is not a monad, since it violates the law of left identity:

futureMonad.point(a) bind f == f(a)

If f throws an exception, the result of the expression on the left hand side will be a failed Future, whereas the right hand side will, of course, throw the exception.

But what are the practical implications of this violation? In which ways can a system fail as a result of this "misbehavior"?


回答1:


It just means, in terms of for comprehensions, that the following refactoring is not semantics-preserving:

for (fut <- Future(a); x <- f(fut)) yield x  ==>  f(a)

But that's just another way of writing the left identity law, really.

To explain that invalid refactoring further:

for (fut <- Future(a); x <- f(fut)) yield x
==>  for (x <- f(a)) yield x  // by left identity law: WRONG, because left identity law does not hold
==>  f(a)                     // by 1st functor law:   WRONG, because previous line was wrong



回答2:


Monads such as Try and Future trade one monad law for another law which is more useful in the context they are supposed to be used: An expression composed from (Try or Future), flatMap, map will never throw a non-fatal exception. Call this the "bullet-proof" principle. So actually this approach really protects you against many failures and left-unit law is failed deliberately.



来源:https://stackoverflow.com/questions/20168677/violation-of-the-left-identity-law-for-future-monads-in-scalaz

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!