7

scalaz的option monoid定义如下:

implicit def optionMonoid[A: Semigroup]: Monoid[Option[A]] = new Monoid[Option[A]] {
  def append(f1: Option[A], f2: => Option[A]) = (f1, f2) match {
    case (Some(a1), Some(a2)) => Some(Semigroup[A].append(a1, a2))
    case (Some(a1), None)     => f1
    case (None, Some(a2))     => f2
    case (None, None)         => None
  }

  def zero: Option[A] = None
}

f2是按名称传递的参数,这意味着每次调用都会评估表达式。刚刚在模式匹配中求值的时候,为什么还要再求值呢?返回Some(a2)应该是相同的结果,并且表达式f2可能非常昂贵。

我错过了什么吗?

Scalaz 的 Option.scala 源码

4

1 回答 1

4

在我看来,它是为了强调问题的对称性和为了清晰而不是为了速度而写的。你不能仅仅放弃第二个参数的惰性,因为Semigroup它是这样定义的,在其他情况下,第二个参数的惰性可能是必不可少的。为了保留问题对称性的视觉表示,您可能只想添加

val g2 = f2  // Force evaluation
(f1, g2) match { ...

或类似的。

(如果可以通过名称参数调用惰性来自动记忆它们,那就太好了。)

于 2013-05-02T22:23:08.387 回答