如何在Scala中使用StringOps的fold方法?

时间:2017-02-07 08:48:21

标签: scala

我试着计算字符串的unicode" Hello"在斯卡拉。在StringOps scala API中,我找到了fold和foldLeft方法,并使用上述两种方法编写了一些代码:

val s = "Hello"
s.fold(1L){(z, i) => z*i}
s.foldLeft(1L){(z, i) => z*i}

通过使用第二个表达式,我可以得到正确的答案,但第一个不能和IDE抱怨"无法解析符号*",任何人都可以解释这个吗?

1 个答案:

答案 0 :(得分:2)

如果查看fold的类型签名:

fold[A1 >: Char](z: A1)(op: (A1, A1) ⇒ A1): A1

你会发现它只对Char的超类型进行操作,因此使你的表达式无法进行,编译器会抛出错误。

foldLeft允许您使用结果类型B

foldLeft[B](z: B)(op: (B, Char) ⇒ B): B

这允许您编写当前表达式。

总结一下:fold期望Char作为其种子参数(当您提供1L作为编译器将抱怨的种子时),而foldLeft期望生成的类型您的op功能。

<强>更新

编译器也认为

s.fold(1L){(z, i) => z}是正确的。这是因为CharLong共享超类型AnyVal。由于fold期望提供Char的超类型AnyVal也有效。这也是编译器抱怨它无法找到函数*的原因,因为它没有在类型AnyVal上定义。

更新2:

如果您真的想使用fold代替foldLeft,则必须事先将s映射到Seq [Long]。即:

s.map(_.toLong).fold(1L){(z, i) => z*i} //returns 9415087488