假设我为Future
:定义了一个Monad
类型类的实例
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
}
严格地说,这不是monad,因为它违反了左身份定律:
futureMonad.point(a) bind f == f(a)
如果f
抛出异常,则左侧表达式的结果将是失败的Future
,而右侧当然会抛出异常。
但这种违规行为的实际含义是什么?一个系统在哪些方面会因为这种"不当行为"而失败?
像Try
和Future
这样的monad用一个monad定律换另一个定律,这在它们应该使用的上下文中更有用:由(Try
或Future
)、flatMap、map组成的表达式永远不会引发非致命异常。这就是"防弹"原则。因此,实际上这种方法确实可以保护您免受许多失败的影响,并且左单位定律是故意失败的。
这只是意味着,就理解而言,以下重构不是语义保留的:
for (fut <- Future(a); x <- f(fut)) yield x ==> f(a)
但实际上,这只是书写左派身份法的另一种方式。
进一步解释无效重构:
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