首页 > 解决方案 > FoldLeft 操作中的 Scala 类型不匹配

问题描述

我对 Scala 很陌生,所以请原谅这可能是对该语言的简单误解。我有一个功能:

def compareNextElemToMinElem(lst: List[Int]) = {
    val max = lst.foldLeft((lst(0),lst(0),0)) { (minSoFar:Int, x:Int, maxDiff:Int) => 
        if (x < minSoFar) (minSoFar, x, maxDiff) 
        if (x - minSoFar > maxDiff) (minSoFar, x, x - minSoFar)
        else (minSoFar, x, x - minSoFar)
    }
    max._3
}

基本上它应该一次一个元素,并跟踪迄今为止元素的最大差异。通过调用,我希望从 foldLeft 调用max._3中返回最终结果。maxDiff我收到一个错误:

type mismatch;
 found   : (Int, Int, Int) => (Int, Int, Int)
 required: ((Int, Int, Int), Int) => (Int, Int, Int)
    val max = lst.foldLeft((lst(0),lst(0),0)) { (minSoFar:Int, x:Int, maxDiff:Int) => 

此外,我必须把(minSoFar:Int, x:Int, maxDiff:Int)而不是以(minSoFar, x, maxDiff)避免missing parameter type错误。这是为什么?

标签: scalafold

解决方案


语法和逻辑似乎都不完全正确,这是一个可能的修复:

def compareNextElemToMinElem(lst: List[Int]) = {
  lst.foldLeft((lst.head, lst.head)) { case ((minSoFar, maxDiff), x) =>
    if (x < minSoFar) (x, maxDiff) 
    else if (x - minSoFar > maxDiff) (minSoFar, x - minSoFar)
    else (minSoFar, maxDiff)
  }._2
}

println(compareNextElemToMinElem(List(1,-2,3,-1,4,8,2)))

印刷

10

这是8 - (-2)

简要说明:

  1. 您想要跟踪两个值:minSoFarmaxDiff,而不是三个。
  2. 您必须查看列表的内容:x必须来自列表,而不是来自上一步传递的“累加器”
  3. fold,一般来说,接受一个接受两个参数的函数:

    list.fold(accumulator0){ (acc, currentValue) => nextAcc }
    
  4. 由于这里您的累加器acc本身就是一个元组,因此您必须在第一个组件上使用 进行模式匹配case,因此:

    list.fold((a0, b0)) { case ((ai, bi), x) => (nextAi, nextBi) }
    
  5. 我不明白你的if-else逻辑,不能保证它符合你的意图。


推荐阅读