我有一个lis
类型的列表List[(Char,Int)]
,需要按字符排序,但我想用sortWith
函数来做。一种方法是使用:
val newlis = lis.sortWith({case ((a,b),(c,d)) => a<c })
但是当我写了auxilary函数时:
def aux2(term: ((Char, Int),(Char, Int)) ): Boolean = term match {
case ((a,b),(c,d)) => a<c
case _ => false
}
lis.sortWith(aux2)
我的类型不匹配。那是为什么?
答案 0 :(得分:2)
之间存在差异
def f(a: A, b: B): C
和
def f(ab: (A, B)): C
当lifted和desugared时,第一个变为Function2[A, B, C]
,而第二个变为Function[(A, B), C]
。虽然基本相同( isomorphic ),但这两种类型必须使用略有不同的语法。
以下是使用(Char, Int)
而非A
和B
的稍微复杂的示例:
def g1(abcd: ((Char, Int), (Char, Int))): Boolean = abcd._1._2 < abcd._2._2
val g1Fun: (((Char, Int), (Char, Int))) => Boolean = g1
// ^^^ ^
// || \ second component of tuple: (Char, Int)
// || first component of tuple: (Char, Int)
// | \
// | single argument of type ((Char, Int),(Char, Int))
// \
// argument list of `g1Fun`, accepts *one* argument
def g2(ab: (Char, Int), cd: (Char, Int)): Boolean = ab._2 < cd._2
val g2Fun: ((Char, Int), (Char, Int)) => Boolean = g2
// ^^ ^
// || second argument of type (Char, Int)
// | \
// | first argument of type (Char, Int)
// \
// argument list of `g2Fun`, needs *two* arguments
lt
中的函数sortWith
的行为类似于第二个函数g2Fun
,而您编写的函数aux2
更像g1Fun
。< / p>
因此,要修复代码,您必须将aux2
定义为二进制操作:
val lis: List[(Char,Int)] = List(('a', 34), ('b', 42))
println(lis.sortWith({case ((a,b),(c,d)) => a < c }))
def aux2(
firstTerm: (Char, Int),
secondTerm: (Char, Int)
): Boolean = (firstTerm, secondTerm) match {
case ((a,b), (c,d)) => a < c
case _ => false
}
println(lis.sortWith(aux2))
为了使它与您所编写的f
相同,sortWith
必须接受稍微不同的功能。
考虑一下:
def watchTheArity(f: ((Int, Int)) => Int): Int = {
f((4, 5))
}
查看包裹(Int, Int)
部分的奇怪的双重parens?
这意味着:“我希望f
以单个元组作为参数”。
因此,这有效:
def f(ab: (Int, Int)): Int = ab._1 + ab._2
println(watchTheArity(f))
但是,如果它被定义为
def watchTheArity2(f: (Int, Int) => Int): Int = {
f(4, 5)
}
那么你需要一个f
来获取两个参数。
编辑通知添加了对括号的Ascii-art说明。