Scala折叠在元组的序列上

时间:2016-07-01 15:31:46

标签: scala

我有以下方法可以应用折叠操作:

def rec(id: String, elems: Seq[(String, MyCase)]) = {
  elems.fold(Seq.empty[(String, Seq[String])] { elem =>
    ....
  }
}

我没有得到的是elem的类型是什么,我不明白为什么它应该是!有线索吗?

3 个答案:

答案 0 :(得分:1)

您错过了{之前的右括号,这就是您的IDE可能认为类型为Nothing的原因。

此外,您可能正在寻找foldLeft,而不是fold(后者的第一个参数必须与序列元素的类型相匹配)。

现在.foldLeftSeq[A]的(简化)签名是:

   foldLeft[B](b: B)(f: (B,A) => B)

正如您所看到的,它需要一个函数,它将Tuple2转换为第一个参数的类型。元组的第一个元素与第一个参数的类型相同,第二个元素的类型与序列的元素相同。

在您的示例中,BSeq[(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
}