FoldLeft 操作中的 Scala 类型不匹配
Scala Type Mismatch in FoldLeft operation
我是 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
}
基本上,它应该 一次处理一个元素,并跟踪迄今为止元素中最大的差异。通过调用 max._3
,我希望 return 来自 foldLeft 调用的最终 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
错误。这是为什么?
语法和逻辑似乎都不完全正确,这里是一个可能的修复:
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)
.
简要说明:
- 您想跟踪两个值:
minSoFar
和 maxDiff
,而不是三个。
- 你要看榜单内容:
x
一定来自榜单,
不是来自上一步 传递的 "accumulator"
fold
,一般来说,接受一个有两个参数的函数:
list.fold(accumulator0){ (acc, currentValue) => nextAcc }
因为这里你的累加器 acc
本身就是一个元组,你必须在第一个组件上与 case
进行模式匹配,所以:
list.fold((a0, b0)) { case ((ai, bi), x) => (nextAi, nextBi) }
我不明白你的if-else
逻辑,不能保证它会按照你的意图行事。
您必须将 minSofar 和 maxDiff 作为 Tuple2 或 pair.So 传递,它应该像下面的代码:
def compareNextElemToMinElem(lst: List[Int]) = {
val max = lst.foldLeft((lst(0),0)) { (p : Tuple2[Int,Int], x:Int) =>
var minSoFar = p._1;
var maxDiff = p._2
if (x < minSoFar) {
maxDiff = maxDiff + minSoFar - x
minSoFar = x
}
if (x - minSoFar > maxDiff){
maxDiff = x - minSoFar
}
(minSoFar,maxDiff)
}
max._2
}
关注此 link 以了解有关 foldleft 参数的更多信息。
我是 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
}
基本上,它应该 一次处理一个元素,并跟踪迄今为止元素中最大的差异。通过调用 max._3
,我希望 return 来自 foldLeft 调用的最终 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
错误。这是为什么?
语法和逻辑似乎都不完全正确,这里是一个可能的修复:
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)
.
简要说明:
- 您想跟踪两个值:
minSoFar
和maxDiff
,而不是三个。 - 你要看榜单内容:
x
一定来自榜单, 不是来自上一步 传递的 "accumulator"
fold
,一般来说,接受一个有两个参数的函数:list.fold(accumulator0){ (acc, currentValue) => nextAcc }
因为这里你的累加器
acc
本身就是一个元组,你必须在第一个组件上与case
进行模式匹配,所以:list.fold((a0, b0)) { case ((ai, bi), x) => (nextAi, nextBi) }
我不明白你的
if-else
逻辑,不能保证它会按照你的意图行事。
您必须将 minSofar 和 maxDiff 作为 Tuple2 或 pair.So 传递,它应该像下面的代码:
def compareNextElemToMinElem(lst: List[Int]) = {
val max = lst.foldLeft((lst(0),0)) { (p : Tuple2[Int,Int], x:Int) =>
var minSoFar = p._1;
var maxDiff = p._2
if (x < minSoFar) {
maxDiff = maxDiff + minSoFar - x
minSoFar = x
}
if (x - minSoFar > maxDiff){
maxDiff = x - minSoFar
}
(minSoFar,maxDiff)
}
max._2
}
关注此 link 以了解有关 foldleft 参数的更多信息。