Considering
object A {
def m(i: Int) = i
val m = (i: Int) => i * 2
}
one gets
scala> A.m(2)
<console>: error: ambiguous reference to overloaded definition,
both value m in object A of type => (Int) => Int
and method m in object A of type (i: Int)Int
match argument types (Int)
A.m(2)
^
Accessing the val can be done with
scala> val fun = A.m
fun: (Int) => Int = <function1>
scala> fun(2)
res: Int = 4
or
scala> A.m.apply(2)
res: Int = 4
but how would one access the def?
It is total rubbish (please, don't do this at home), but you can do it by assigning A to a variable of structural type, that has only the first m.
val x : { def m(i:Int):Int } = A
x.m(10)
Related
What is the logical reason that the first form works and not the second?
scala> val d = (a: Int, b: Int) => a + b
d: (Int, Int) => Int = <function2>
scala> val d = (a: Int)(b: Int) => a + b
<console>:1: error: not a legal formal parameter.
Note: Tuples cannot be directly destructured in method or function parameters.
Either create a single parameter accepting the Tuple1,
or consider a pattern matching anonymous function: `{ case (param1, param1) => ... }
val d=(a:Int)(b:Int)=>a+b
Because multiple parameter lists aren't allowed on function declarations. If you want to curry a function, you do:
scala> val d: Int => Int => Int = a => b => a + b
d: Int => (Int => Int) = $$Lambda$1106/512934838#6ef4cbe1
scala> val f = d(3)
f: Int => Int = $$Lambda$1109/1933965693#7e2c6702
scala> f(4)
res6: Int = 7
You can also create a single parameter list and partially apply it:
scala> val d = (a: Int, b: Int) => a + b
d: (Int, Int) => Int = $$Lambda$1064/586164630#7c8874ef
scala> d(4, _: Int)
res2: Int => Int = $$Lambda$1079/2135563436#4a1a412e
We partially applied d with 4, and we got back a function, Int => Int, which means when we supply the next argument, we'll get the result:
scala> res2(3)
res3: Int = 7
We can also create a named method, and use eta-expansion to create a curried function out of it:
scala> def add(i: Int)(j: Int): Int = i + j
add: (i: Int)(j: Int)Int
scala> val curriedAdd = add _
curriedAdd: Int => (Int => Int) = $$Lambda$1115/287609100#f849027
scala> val onlyOneArgumentLeft = curriedAdd(1)
onlyOneArgumentLeft: Int => Int = $$Lambda$1116/1700143613#77e9dca8
scala> onlyOneArgumentLeft(2)
res8: Int = 3
Function currying is possible.
val curryFunc = (a: Int) => (b: Int) => a + b
curryFunc now has the type Int => (Int => Int)
I am new to scala and was playing around with few concepts but got stuck with following one.
If i create a method like
def sample(value:Int) = {(x:Int)=>x+1}
This works in Scala and can be tested as sample(100), but I am not able to understand as how a method and literal here can be clubbed. Can someone explain what exactly is happening?
The parameter value here is never used and is therefore redundant. The method sample() returns a function which takes one integer parameter (which is discarded) and then adds 1 to it. So you get:
scala> def sample(value:Int) = { (x:Int) => x + 1 }
sample: (value: Int)Int => Int
scala> sample(100)
res2: Int => Int = <function1>
scala> sample(100)(10)
res3: Int = 11
scala> val f = sample(99)
f: Int => Int = <function1>
scala> f(1)
res4: Int = 2
You could use the value parameter in the following way:
scala> def plusX(value:Int) = { (x:Int) => x + value}
plusX: (value: Int)Int => Int
scala> val plus10 = plusX(10)
plus10: Int => Int = <function1>
scala> plus10(15)
res7: Int = 25
Now plusX creates a function which takes a integer and adds the value value to it
Given
scala> def method(x: Int) = x
method: (x: Int)Int
scala> val func = (x: Int) => x
func: Int => Int = <function1>
Consider the following code:
scala> method _
res0: Int => Int = <function1>
scala> func(_)
res1: Int => Int = <function1>
scala> func _
res2: () => Int => Int = <function0>
I can understand that res0 is eta expansion and res1 is equivalent to lambda function (x) => func(x). But I cannot figure out the output of res2. Could anyone please explain that for me?
This is actually a bit tricky. First, let's see what happens outside REPL:
It doesn't work when func is a local variable:
object Main extends App {
def foo() = {
val f = (_: Int) + 1
f _
}
println(foo())
}
[error] /tmp/rendereraEZGWf9f1Q/src/main/scala/test.scala:8: _ must follow method; cannot follow Int => Int
[error] f _
[error] ^
But if you put it outside def foo, it compiles:
object Main extends App {
val f = (_: Int) + 1
val f1 = f _
println(f1)
}
because f is both a field of Main and a method without arguments which returns the value of this field.
The final piece is that REPL wraps each line into an object (because Scala doesn't allow code to appear outside a trait/class/object), so
scala> val func = (x: Int) => x
func: Int => Int = <function1>
is really something like
object Line1 {
val func = (x: Int) => x
}
import Line1._
// print result
So func on the next line refers to Line1.func which is a method and so can be eta-expanded.
You've used the eta Expansion to turn res2 into a function that takes 0 parameters and returns a function that takes a single parameter.
res2: () => Int => Int = <function0>
So you can now do this:
val zero = func _
val f: Int => Int = zero()
To answer your question about res2 - the appended underscore _ syntax is used to partially apply a function.
So.
scala> func _
Means you have partially applied your <function1>.
This results in a new curried form, the first function of which takes zero arguments (hence <function0>)
() =>
Which returns your original <function1> which takes 1 argument.
Int => Int = <function1>
The complete result being the chain of functions.
res2: () => Int => Int = <function0>
The rule that might be useful for you to remember is that functions associate to the right so the following are equivalent.
() => Int => Int
() => (Int => Int)
This other post might be useful reading for you.
val func1 = func _
This returns a function0 which takes no arguments and returns the func function.
You can use this like:
func1()(2) // outputs 2
You can continue doing this kind of expansion ad infinitum:
val func2 = func1 _
func2()()(2) // outputs 2
I am trying to declare a simple method in scala with multiple parameter lists.
These two work.
scala> def add(a:Int, b:Int) = a+ b
add: (a: Int, b: Int)Int
scala> def add(a:Int)(b:Int) = a + b
add: (a: Int)(b: Int)Int
This does not...
scala> val add = (a:Int)(b:Int)=>a + b
<console>:1: error: not a legal formal parameter.
Note: Tuples cannot be directly destructured in method or function parameters.
Either create a single parameter accepting the Tuple1,
or consider a pattern matching anonymous function: `{ case (param1, param1) => ... }
val add = (a:Int)(b:Int)=>a + b
But why ... all I am trying to do is to assign a anonymous function which takes multiple parameter lists to a value. that works with a single parameter list but not with multiple parameter lists.
It's just a matter of syntax when declaring the curried arguments.
scala> val add = (a:Int) => (b:Int) => a + b
add: Int => (Int => Int) = <function1>
scala> add(4)
res5: Int => Int = <function1>
scala> res5(9)
res6: Int = 13
Example of anonymous usage:
scala> def doit(f: Int => Int => String): String = f(2)(5)
doit: (f: Int => (Int => String))String
scala> doit(a => b => (a+b).toString)
res8: String = 7
After having discovered that currying multi parameter-groups method is possible, I am trying to get a partially applied function which requires implicit parameters.
It seams not possible to do so. If not could you explain me why ?
scala> def sum(a: Int)(implicit b: Int): Int = { a+b }
sum: (a: Int)(implicit b: Int)Int
scala> sum(3)(4)
res12: Int = 7
scala> val partFunc2 = sum _
<console>:8: error: could not find implicit value for parameter b: Int
val partFunc2 = sum _
^
I use a singleton object to create this partially applied function and I want to use it in a scope where the implicit int is defined.
That is because you don't have an implicit Int in scope. See:
scala> def foo(x: Int)(implicit y: Int) = x + y
foo: (x: Int)(implicit y: Int)Int
scala> foo _
<console>:9: error: could not find implicit value for parameter y: Int
foo _
^
scala> implicit val b = 2
b: Int = 2
scala> foo _
res1: Int => Int = <function1>
The implicit gets replaced with a real value by the compiler. If you curry the method the result is a function and functions can't have implicit parameters, so the compiler has to insert the value at the time you curry the method.
edit:
For your use case, why don't you try something like:
object Foo {
def partialSum(implicit x: Int) = sum(3)(x)
}
scala> object MySingleton {
| def sum(a: Int)(implicit b: Int): Int = { a+b }
|
|
| def caller(a: Int) = {
| implicit val b = 3; // This allows you to define the partial below
| def pf = sum _ // and call sum()() without repeating the arg list.
| pf.apply(a)
| }
| }
defined module MySingleton
scala> MySingleton.caller(10)
res10: Int = 13