简体   繁体   中英

Difference between these two method definitions

What's the difference between these two definitions?:

def sayTwords(word1: String, word2: String) = println(word1 + " " + word2)
def sayTwords2(word1: String)(word2: String) = println(word1 + " " + word2)

What is the purpose of each?

The second is curried, the first isn't. For a discussion of why you might choose to curry a method, see What's the rationale behind curried functions in Scala?

sayTwords2 allows the method to be partially applied.

val sayHelloAnd = sayTwords2("Hello")
sayHelloAnd("World!")
sayHaelloAnd("Universe!")

Note you can also use the first function in the same way.

val sayHelloAnd = sayTwords("Hello", _:String)
sayHelloAnd("World!")
sayHelloAnd("Universe!")
def sayTwords(word1: String, word2: String) = println(word1 + " " + word2)
def sayTwords2(word1: String)(word2: String) = println(word1 + " " + word2)

The first contains a single parameter list. The second contains multiple parameter lists.

They differ in following regards:

  1. Partial application syntax. Observe:

     scala> val f = sayTwords("hello", _: String) f: String => Unit = <function1> scala> f("world") hello world scala> val g = sayTwords2("hello") _ g: String => Unit = <function1> scala> g("world") hello world 

    The former has a benefit of being positional syntax. Thus you can partially apply arguments in any positions.

  2. Type inference. The type inference in Scala works per parameter list, and goes from left to right. So given a case, one might facilitate better type inference than other. Observe:

     scala> def unfold[A, B](seed: B, f: B => Option[(A, B)]): Seq[A] = { | val s = Seq.newBuilder[A] | var x = seed | breakable { | while (true) { | f(x) match { | case None => break | case Some((r, x0)) => s += r; x = x0 | } | } | } | s.result | } unfold: [A, B](seed: B, f: B => Option[(A, B)])Seq[A] scala> unfold(11, x => if (x == 0) None else Some((x, x - 1))) <console>:18: error: missing parameter type unfold(11, x => if (x == 0) None else Some((x, x - 1))) ^ scala> unfold(11, (x: Int) => if (x == 0) None else Some((x, x - 1))) res7: Seq[Int] = List(11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) scala> def unfold[A, B](seed: B)(f: B => Option[(A, B)]): Seq[A] = { | val s = Seq.newBuilder[A] | var x = seed | breakable { | while (true) { | f(x) match { | case None => break | case Some((r, x0)) => s += r; x = x0 | } | } | } | s.result | } unfold: [A, B](seed: B)(f: B => Option[(A, B)])Seq[A] scala> unfold(11)(x => if (x == 0) None else Some((x, x - 1))) res8: Seq[Int] = List(11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM