【问题标题】:Scala fold over String results in "type mismatch; found: Any"Scala折叠字符串导致“类型不匹配;发现:任何”
【发布时间】:2014-05-05 04:51:03
【问题描述】:

我在 Scala 中玩弄折叠,不知何故,最终尝试通过执行以下操作来测试字符串是否仅包含唯一字符:

str
  .fold(""){ (x, y) => if (!(x contains y)) x + y else x }
  .size == str.size

这会导致错误

error: type mismatch;
found: Any
required: String

显然指向y的值。

谁能提供对此的见解?

我没想到会出现这种行为,我能找到的最接近的答案是"Scala assumes wrong type when using foldLeft,",这很相似,但并不能完全阐明问题。

【问题讨论】:

    标签: scala functional-programming


    【解决方案1】:

    您应该使用foldLeft 而不是fold:

    str
      .foldLeft(""){ (x, y) => if (!(x contains y)) x + y else x }
      .size == str.size
    

    fold 的签名是:

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

    所以fold 期望元素类型是累加器类型的下限。在String 的情况下元素类型是Char,所以A1 的可能类型是Char、AnyVal 和Any。你传递了一个String,所以Any是唯一的通用类型,这意味着x和y有类型Any,它没有contains方法。

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

    【讨论】:

    • 基本原理是:fold 是为并行计算而设计的,因此它仅在您可以组合从列表中任何位置开始的两个列表元素时才有效,例如,在中间。这要求函数是关联的,并且不需要提供基本案例值。另一方面,foldleft 和 foldright 更通用(您的累积值可以是与列表中的项目不同的类型 - 例如,将列表中所有字符串的 length 相加) , 并与非关联函数一起工作(但不可并行化)。
    猜你喜欢
    • 2015-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    • 1970-01-01
    • 2018-08-02
    • 2010-11-27
    • 2019-04-30
    相关资源
    最近更新 更多