Scalaz提供了一个名为fold
的方法,用于各种ADT,例如Boolean
,Option[_]
,Validation[_, _]
,Either[_, _]
等。该方法基本上需要使用与给定ADT的所有可能情况对应的函数。换句话说,就是下面所示的模式匹配:
x match {
case Case1(a, b, c) => f(a, b, c)
case Case2(a, b) => g(a, b)
.
.
case CaseN => z
}
等同于:
x.fold(f, g, ..., z)
一些示例:
scala> (9 == 8).fold("foo", "bar")
res0: java.lang.String = bar
scala> 5.some.fold(2 *, 2)
res1: Int = 10
scala> 5.left[String].fold(2 +, "[" +)
res2: Any = 7
scala> 5.fail[String].fold(2 +, "[" +)
res6: Any = 7
同时,Traversable[_]
类型也有一个同名操作,它遍历集合并对其元素执行某些操作,并累积结果值。例如:
scala> List(2, 90, 11).foldLeft("Contents: ")(_ + _.toString + " ")
res9: java.lang.String = "Contents: 2 90 11 "
scala> List(2, 90, 11).fold(0)(_ + _)
res10: Int = 103
scala> List(2, 90, 11).fold(1)(_ * _)
res11: Int = 1980
为什么这两个操作要使用相同的名称——fold
/catamorphism?我没有看到它们之间有任何相似性或关系。我错过了什么吗?