按块的顺序折叠



我想在我的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=>String")?

所以我试着声明类型:

type MyBlockType = String => String

并以这种方式声明我的序列:

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不将其识别为对象呢?

请帮我指出我做错了什么。

谢谢,Raka

在这种情况下,您需要"foldLeft":

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

对于fold,初始值和Seq中的每个值都需要具有相同的类型。但您的初始(和输出)值是String,但集合是String=>String

方法签名:

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

因此,如果你想使用fold,你的初始值需要是String=>String,例如,对于identity,它将是:

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

最新更新