wang kai
wang kai

Reputation: 1747

Why sortWith(lt: (A, A) => Boolean) require a function with two params but can use compareTo which have only one param?

As https://www.scala-lang.org/api/current/scala/collection/immutable/List.html#sortWith(lt:(A,A)=%3EBoolean) :

List("Steve", "Tom", "John", "Bob").sortWith(_.compareTo(_) < 0) = List("Bob", "John", "Steve", "Tom")

the param of sortWith is:

lt: (A, A) => Boolean

where a function with two params and return a boolean

but compareTo have only one param:

def compareTo(that: A): Int

if compareTo is a function,it have two params.but it's scala,so compareTo is a method,it's have only one param

so why there can use compareTo in sortWith?It seems not accord with the type signature of sortWith

Upvotes: 0

Views: 131

Answers (1)

Mario Galic
Mario Galic

Reputation: 48410

This usage of underscore is known as Placeholder Syntax for Anonymous Functions:

Such an expression represents an anonymous function where subsequent occurrences of underscores denote successive parameters.

Note each underscore refers to different parameter so for example

_ + _

expands to

(x1, x2) => x1 + x2

Also expression _ + _ makes use of point-free syntax as opposed to

_.+(_)

for example

List("Steve", "Tom", "John", "Bob").reduce((x1: String, x2: String) => x1.+(x2)) // : String = "SteveTomJohnBob"
List("Steve", "Tom", "John", "Bob").reduce((x1, x2) => x1.+(x2)) // : String = "SteveTomJohnBob"
List("Steve", "Tom", "John", "Bob").reduce(_.+(_)) // : String = "SteveTomJohnBob"
List("Steve", "Tom", "John", "Bob").reduce(_ + _) // : String = "SteveTomJohnBob"

so now it should be clearer why expression _.compareTo(_) < 0 works

List("Steve", "Tom", "John", "Bob").sortWith(_.compareTo(_) < 0) // : List[String] = List("Bob", "John", "Steve", "Tom")
List("Steve", "Tom", "John", "Bob").sortWith((x1, x2) => x1.compareTo(x2) < 0) // : List[String] = List("Bob", "John", "Steve", "Tom")

Another way to see this let's type-ascribe the sugared expression

scala> (_.compareTo(_) < 0): ((String, String) => Boolean)
val res0: (String, String) => Boolean = $Lambda$7865/418832725@18987bf5

Upvotes: 3

Related Questions