为什么在Play 2.0.2中有Form的折叠方法?

Hen*_*son 5 api scala playframework

我是指这个:

http://www.playframework.org/documentation/api/2.0.2/scala/index.html#play.api.data.Form

如果搜索名为fold的方法,则会显示用于处理表单的方法.这种方法被称为折叠是否有原因?鉴于折叠已经具有列表类对象的含义,似乎这个名称很容易引起混淆.

Tra*_*own 10

foldForm是相当接近foldEither在Scala的标准库类,它同样经常被用来捕获过程的结果,可能要么成功(在这种情况下,你有一个Right包含结果)或失败(在这种情况下,你有一个Left含有错误,或者可能剩输入等).所以我将Either在这里作为一个例子.只是想象Form[T]一下Either[Form[T], T]如果必要的话.

折叠收藏品

我们可以(非常非正式地)将列表想象为具有许多不同的"形状"(空列表,长度为1,长度为2的列表等),以及fold(或者foldLeft,在以下示例中)作为折叠任何列表的方法适当的类型到一种东西,无论它的形状是什么:

scala> def catInts(xs: List[Int]): String = xs.foldLeft("")(_ + _.toString)
catInts: (xs: List[Int])String

scala> catInts(List(1, 2, 3, 4))
res0: String = 1234

scala> catInts(Nil)
res1: String = ""
Run Code Online (Sandbox Code Playgroud)

折叠在任一/表格上

类似地,我们可以想象Either有两个形状(RightLeft),并且它fold作为一种方法,它采用Either任何一种形状并返回一种形状.假设我们有以下方法将字符串解析为整数并返回Either:

def parseInt(s: String): Either[String, Int] =
  try Right(s.toInt) catch {
    case _: NumberFormatException => Left(s)
  }
Run Code Online (Sandbox Code Playgroud)

以下方法fold用于折叠Either:

def toDefault(e: Either[String, Int]): Int = e.fold(_ => 42, identity)
Run Code Online (Sandbox Code Playgroud)

我们可以这样使用:

scala> toDefault(parseInt("AAARGH!!"))
res2: Int = 42

scala> toDefault(parseInt("123"))
res3: Int = 123
Run Code Online (Sandbox Code Playgroud)

这显然是非常印象派和手工波浪,但它可能有助于更直观地了解不同fold方法从根本上是同一种事物.您可以在上面的评论中找到我链接的问题,或者在catamorphisms上查看维基百科条目以获取更多详细信息.