字符串上的Scala折叠导致"类型不匹配;找到:任何"

Kat*_*ine 2 functional-programming scala

我正在玩Scala中的折叠,无论出于何种原因,最终尝试通过执行以下操作来测试String是否仅包含唯一字符:

str
  .fold(""){ (x, y) => if (!(x contains y)) x + y else x }
  .size == str.size
Run Code Online (Sandbox Code Playgroud)

这导致错误

error: type mismatch;
found: Any
required: String
Run Code Online (Sandbox Code Playgroud)

显然指向了价值y.

谁能提供这方面的见解?

我不会期望这种行为,而我能找到的最接近的答案是"使用foldLeft时Scala假定错误的类型",这是类似的,但并不能完全澄清事情.

Lee*_*Lee 7

您应该使用foldLeft而不是fold:

str
  .foldLeft(""){ (x, y) => if (!(x contains y)) x + y else x }
  .size == str.size
Run Code Online (Sandbox Code Playgroud)

签名fold是:

fold[A1 >: Char](z: A1)(op: (A1, A1) ? A1): A1 
Run Code Online (Sandbox Code Playgroud)

因此,fold期望元素类型是累加器类型的下限.元素类型是Char在的情况下String,这样的可能类型A1Char,AnyValAny.你传递一个String这样Any是唯一的常见类型,这意味着xy有型Any,其中没有一个contains方法.

您需要将累加器类型与元素类型不同,因此您需要使用foldLeft.

  • 其基本原理是:“fold”是为并行计算而设计的,因此只有当您可以从列表中的任何位置(例如中间)开始组合两个列表元素时,它才有效。这要求该函数是关联的,并且不需要提供基本情况值。另一方面,“foldleft”和“foldright”更通用(您的累积值可以是与列表中的项目不同的类型——例如对列表中所有字符串的*长度*求和),并且可以使用/非关联函数(但不可​​并行)。 (2认同)