Scala函数输入问题

时间:2018-02-21 17:03:29

标签: scala

我有一个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)

我的类型不匹配。那是为什么?

1 个答案:

答案 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)而非AB的稍微复杂的示例:

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说明。