Manu Chadha - 1 year ago 64
Scala Question

# unable to understand function's signature of scala apis

I am studying lists and am writing sample examples of its methods.

The 'andThen' is defined as follows

``````def andThen[C](k: (A) ⇒ C): PartialFunction[Int, C]
``````

I understand that I have to pass a function literal to andThen. So I created following code which works.

``````scala> val l = List (1,2,3,4)
l: List[Int] = List(1, 2, 3, 4)

//x:Int works
scala> val listAndThenExample = l.andThen((x:Int) => (x*2))
listAndThenExample: PartialFunction[Int,Int] = <function1>

//underscore works
scala> val listAndThenExample = l.andThen(_*2)
listAndThenExample: PartialFunction[Int,Int] = <function1>
``````

As the list is of Integers, A has to be Int. C can be anything depending on the output of function literal

The above makes sense.

Later I tried
`applyOrElse`
. Its signature is as follows

``````def applyOrElse[A1 <: Int, B1 >: A](x: A1, default: (A1) ⇒ B1): B1
``````

From above, I understand that A1 can be Int or its subclass (upperbound) and some B1 will be the return type (depending on what I do in default function).

If my understanding of A1 and B1 is correct then x will be either Int or its subclass and the default function literal should take Int (or subclass) and return some B1. I tried to call the function as follows but it doesn't work when I use
`y:Int`
but works when I use
`_:Int`
. I do not understand why

``````scala> val l = List (1,2,3,4)
l: List[Int] = List(1, 2, 3, 4)

//this doesnt work
cala> val listApplyOrElse = l.applyOrElse(y:Int,(x:Int)=>println("Wrong arg "+x))
val listApplyOrElse = l.applyOrElse(y:Int,(x:Int)=>println("Wrong arg "+x))
^
//but underscor works
scala> val listApplyOrElse = l.applyOrElse(_:Int,(x:Int)=>println("Wrong arg "+x))
listApplyOrElse: Int => AnyVal = <function1>
``````

Question - Why did both x:Int and _:Int worked for andThen but not for applyOrElse?
Question - what is 'A' and why is B1 related to A?

According to the documentation, `applyOrElse(x, default)` is equivalent to

``````if (pf isDefinedAt x) pf(x) else default(x)
``````

In this case your partial function is a list i.e. a function from indices (0 to 3) to values (1,2,3,4). So when you do

``````l.applyOrElse(y,(x:Int)=>println("Wrong arg "+x))
``````

you're saying "Call `l(y)` if it makes sense, otherwise `println("Wrong arg"+y)`". The compiler reasonably responds, "What is `y`?"

If you use an actual value it works as expected

``````l.applyOrElse(3 ,(x:Int)=>println("Wrong arg "+x)) // returns 4
l.applyOrElse(8 ,(x:Int)=>println("Wrong arg "+x)) // prints Wrong arg 8
``````

Using an underscore does something completely different, you get a partially applied function (which is completely different from a partial function!)

``````val f = l.applyOrElse(_:Int, (x:Int)=>println("Wrong arg "+x))
f(8) // prints Wrong arg 8
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download