我有以下方法可以应用折叠操作:
def rec(id: String, elems: Seq[(String, MyCase)]) = {
elems.fold(Seq.empty[(String, Seq[String])] { elem =>
....
}
}
我没有得到的是elem的类型是什么,我不明白为什么它应该是!有线索吗?
答案 0 :(得分:1)
您错过了{
之前的右括号,这就是您的IDE可能认为类型为Nothing
的原因。
此外,您可能正在寻找foldLeft
,而不是fold
(后者的第一个参数必须与序列元素的类型相匹配)。
现在.foldLeft
上Seq[A]
的(简化)签名是:
foldLeft[B](b: B)(f: (B,A) => B)
正如您所看到的,它需要一个函数,它将Tuple2
转换为第一个参数的类型。元组的第一个元素与第一个参数的类型相同,第二个元素的类型与序列的元素相同。
在您的示例中,B
为Seq[(String, Seq[String])]
,序列元素为(String, MyCase)
。因此,该函数的输入类型将具有如下可怕的元组:
(Seq[(String, Seq[String])], (String, MyCase))
答案 1 :(得分:1)
这是由于您不仅希望fold
,还希望map
元组,请参阅fold方法签名:
def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op)
输入类型和输出类型必须相同:A1
,
所以如果想要映射,您可能想尝试foldLeft
:
def foldLeft[B](z: B)(op: (B, A) => B): B =
输出类型B
有一个泛型而不限于A
。
我们也可以找到fold
源代码正在调用:
def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op)
使用foldLeft
可能像:
elements.fold(Seq.empty[(String, Seq[String])])((a, b) => a ++ Seq((b._1, Seq[String]())))
答案 2 :(得分:0)
第二次编辑: 我是个白痴。折叠必须返回与输入类型相同的值。 例如,用foldLefts替换所有下面的折叠,它可以工作。 您无法在标准折叠中转换数据类型。 它正在为我编译,但我没有注意到返回类型没用。
折叠中的第二个参数是函数:
(ResultType, SingleElement) => Result Type
在这种情况下
(Seq[(String, Seq[String])], Seq[(String, MyCase)]) => Seq[(String, Seq[String])]
您的代码在第二个参数上只有一个输入,因此编译器不知道它是什么。所以看起来应该是这样的:
elems.foldLeft(Seq.empty[(String, Seq[MyCase])] {(zeroSeq, nextElem) =>
//zeroSeq: Seq.empty[(String, Seq[MyCase]
//nextElem: (String, MyCase)
}
编辑:
以下例如编译:
case class MyCase(x: String)
val elems: Seq[(String, MyCase)] = Seq(("Hi", MyCase("B")))
elems.foldLeft(Seq.empty[(String, Seq[MyCase])]){(z, s) =>
z
}