Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class constructor declaration... Two ways of declaring the same thing?

I would like an explanation of difference for example between this declaration:

class Clazz(param1: String, param2: Integer)

and this one:

class Clazz(param1: String)(param2: Integer)

Does second declaration affect just the way of instantiating the objects or is there any deeper reason I don't know about.

One reason I thought about would be multiple variable length of parameters for example:

class Clazz(param1: String*)(param2: Integer*)

So are there any others?

like image 354
PrimosK Avatar asked Feb 16 '12 09:02

PrimosK


2 Answers

#1 Type inference. It goes from left to right and is done per parameter list.

scala> class Foo[A](x: A, y: A => Unit)
defined class Foo

scala> new Foo(2, x => println(x))
<console>:24: error: missing parameter type
              new Foo(2, x => println(x))
                         ^

scala> class Foo[A](x: A)(y: A => Unit)
defined class Foo

scala> new Foo(2)(x => println(x))
res22: Foo[Int] = Foo@4dc1e4

#2 Implicit parameter list.

scala> class Foo[A](x: A)(implicit ord: scala.Ordering[A]) {
     |   def compare(y: A) = ord.compare(x, y)
     | }
defined class Foo

scala> new Foo(3)
res23: Foo[Int] = Foo@965701

scala> res23 compare 7
res24: Int = -1

scala> new Foo(new {})
<console>:24: error: No implicit Ordering defined for java.lang.Object.
              new Foo(new {})
              ^
like image 109
missingfaktor Avatar answered Nov 14 '22 19:11

missingfaktor


In the second version you are declaring a curried primary constructor for Clazz. So the difference between the two versions is the same as difference between "normal" and curried functions in Scala, i.e.

def foo(param1: String, param2: Int)

def foo(param1: String)(param2: Int)

Most of the time both declarations can be used interchangeably but if you often need to curry function then it makes more sense to declare it in curried form. Note you can also convert a normal function or even constructor into a curried form, for e.g you could transform your normal Clazz constructor into curried form using this:

(new Clazz(_, _)).curried

You also need multiple parameter lists if you are passing an implicit value (as the keyword implicit applies to the complete parameter list)

like image 24
elk Avatar answered Nov 14 '22 18:11

elk