折叠块序列

时间:2014-11-07 19:38:13

标签: scala functional-programming fold method-chaining

我想在我的Scala代码中实现操作链。我以为我可以使用“折叠”。所以,假设我的行为序列如此声明:

val chainOfActions: Seq[String => String] = Seq(
  {resultFromPreviousAction => 
    println("Inside the first action")
    "Result from the first action"
  },
  {resultFromPreviousAction => 
    println("Inside the second action")
    resultFromPreviousAction + " > " + "Result from the second action"
  }
)

上面的代码编译(我在scala控制台内部尝试过)。

接下来将应用折叠:

chainOfActions.fold("") { (intermediateText, action) =>
  action(intermediateText)
}

但是上面的代码给出了以下错误:

<console>:10: error: Object does not take parameters
                action(intermediateText)

嗯...为什么我的动作会失去它的类型(我期待类型为“String =&gt; String”)?

所以我尝试声明类型:

type MyBlockType = String => String

以这种方式宣布我的Seq:

val chainOfActions: Seq[MyBlockType] = Seq(
  {resultFromPreviousAction => 
    println("Inside the first action")
    "Result from the first action"
  },
  {resultFromPreviousAction => 
    println("Inside the second action")
    resultFromPreviousAction + " > " + "Result from the second action"
  }
)

仍然,得到同样的错误。所以,我试着检查“行动”的实际类型......:

chainOfActions.fold("") { (intermediateText, action) =>
  println(action.getClass)
  "Test it"
}

我在控制台中收到此信息:

class $line101.$read$$iw$$iw$$anonfun$1
class $line101.$read$$iw$$iw$$anonfun$2
res58: Object = Test it

所以......,这是正确的(这是一个功能)。但是为什么Scala不承认它是对象?

请帮我指出我做错的地方。

谢谢, 拉嘎

1 个答案:

答案 0 :(得分:4)

在这种情况下,您需要&#39; foldLeft&#39;:

val result = chainOfActions.foldLeft("") {
  case (intermediateText, action) => action(intermediateText)
}

对于折叠,您需要为初始值和Seq中的每个值使用相同的类型。但是您的初始(和输出)值是String,但集合是String =&gt;串

方法签名:

 def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1
 def foldLeft[B](z: B)(op: (B, A) => B): B

因此,如果你想使用fold,你的初始值必须是String =&gt;字符串,例如带有标识的字符:

val result = chainOfActions.fold(identity[String] _)((l, r) => l andThen r).apply("")