I am new in Scala and I just came across a situation that I would like someone could explain me.
When watching a Martin Odersky's course I found the following script he uses to explain functions which return a function
val tolerance = 0.0001
def isCloseEnough(x : Double, y : Double) = abs((x - y)/ x) / x < tolerance
def fixedPoint(f : Double => Double)(firstGuess: Double) = {
def iterate(guess: Double): Double = {
val next = f(guess)
if(isCloseEnough(guess,next))next
else iterate(next)
}
iterate(firstGuess)
}
fixedPoint(x => 1 + x/2)(1)
def averageDamp(f: Double => Double)(x: Double) = (x + f(x))/2
def sqrt(x : Double) = fixedPoint(averageDamp(y => x/y))(1)
sqrt(2)
I understand perfectly how the scrip works, but I didn't expect this line:
fixedPoint(averageDamp(y => x/y))(1)
I know that thanks to Currying, Scala let us write functions with several parameter list. So the call to fixedPoint passing as parameter the result of avergaDamp and (1) is clear for me.
What I don't understand is how averageDamp uses the second parameter list of fixedPoint when it itself is inside the first parameter list. I though that would be a different scope, so I was expecting something like:
fixedPoint(averageDamp(y => x/y)(1))(1)
What is the property of Scala which allow us to implement the currying in this way? Is something similar to an implicit applied to a parameter list?
Thanks for your time
This is just how multiple parameter lists work: averageDamp(y => x/y) is equivalent to z => averageDamp(y => x/y)(z) and so its type is Double => Double.
If you wrote fixedPoint(averageDamp(y => x/y)(1))(1) as you expect, it would have a type mismatch because averageDamp(y => x/y)(1) has type Double and fixedPoint needs Double => Double.
Implicits aren't relevant here.
This line works because in the following expression:
fixedPoint(averageDamp(y => x/y))(1)
function "averageDamp(y => x/y)" is "passed by name" i.e. it will not be evaluated while passing to function "fixedPoint" but will be evaluated when it is called from inside "fixedPoint".
value "(1)" is just pass to argument "firstGuess" of "fixedPoint" which will be supplied to parameter "guess" inside the function definition in following expression:
val next = f(guess)
Related
For example, if given Math.sqrt and 2.0, it computes Math.sqrt(Math.sqrt(2.0)).
Using the function:
def applyTwice[A](f: A => A, argument: A) = ???
Then testing the above example
If I correctly understand your question, you want to apply a function twice to an argument and test it too.
For example, if you need to apply Math.sqrt twice to an argument, you can achieve it as shown in below code:
val sqrt: Double => Double = Math.sqrt
def applyTwice[A](f: A => A, d: A) = {
f(f(d))
}
println(applyTwice[Double](sqrt, 625))
assert(applyTwice[Double](sqrt, 625) == 5.0) // will check if applyTwice return 5.0
I am following a course from coursera where this example appears in the lecture but when I try and run it, it throws an error as follows:
missing argument list for method mapReduce in object HelloWorld
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing mapReduce _ or mapReduce(_,_,_)(_,_) instead of mapReduce.
var doo = mapReduce(x => x,(x,y)=>x*y,0)
Below is the code that I want to execute.
def mapReduce(map: Int => Int, combine: (Int,Int)=>Int,
zero: Int)(a: Int,b: Int): Int = {
if (a>b) zero
else combine(map(a), mapReduce(map,combine,zero)(a+1,b))
}
var doo = mapReduce(x => x, (x,y)=>x*y, 0)
println(doo(1,4))
mapReduce wants two argument lists, but your are giving it one.
Try this:
val doo = mapReduce(x => x, (x,y) => x*y, 0) _
or equivalently,
val doo = mapReduce(identity, _*_, 0) _
The _ in the end stands for the second argument list. It tells the compiler that you want the suffixed value to be taken as a functional value rather than an expression to be evaluated.
You can also give compiler a hint to make the conversion happen automatically by explicitly declaring the expected type of the expession:
val doo: (Int, Int) => Int = mapReduce(identity, _*_, 0)
And don't use vars. They are evil. Just pretend, there is no such keyword in scala, until you learn enough of the language to be able to recognize the extremely rare cases when it is actually needed.
You have to define a undescore parameter in order to create a curried function. Like this:
scala> var doo = mapReduce(x => x, (x,y)=>x*y, 0) _
doo: (Int, Int) => Int = <function2>
scala> println(doo(1,4))
0
I am composing function literals, though unlike most examples I've seen I'm starting with a multi-argument function that is then curried.
I have:
//types
case class Thing1(v: Double)
case class Thing2(v: Double)
case class Thing3(v: Double)
type Multiplier = Double
//functions
val f1 = (t: Thing1, m: Multiplier) => Thing2(m * t.v)
val f2 = (t: Thing2) => Thing3(t.v)
I want to compose f1 and f2 to get a combined function
Thing1 => (Multiplier => Thing3)
As expected, the following doesn't compile:
val fcomposed1 = f1.curried.andThen(f2) // does not compile
By experimentation, I was able to work out that the following does compile and has the right signature for fcomposed:
val fcomposed2 = f1.curried(_:Thing1).andThen(f2)
I've read various sources like What are all the uses of an underscore in Scala? and possibly relevant Why does Scala apply thunks automatically, sometimes? but unfortunately I still cannot work out exactly step-by-step what is happening here and why it works.
Furthermore, I would expect the above separated into two expressions to work identically to fcomposed2, however instead the second does not compile:
val f1partial = f1.curried(_:Thing1)
val fcomposed3 = f1partial.andThen(f2) // does not compile - same error as fcomposed1
Looks like f1partial returns the same signature as f1.curried, which makes me wonder further how the earlier fcomposed2 works.
Could someone please explain both behaviours step by step?
Here, the _ is acting as syntactical sugar for a lambda expression, but at a level you might not expect.
f1.curried has type Thing1 => Multiplier => Thing2
f1.curried(_:Thing1) is the same as { x: Thing1 => f1.curried(x) }. Since the result of f1.curried(x) has type Multiplier => Thing2, the final type of the whole expression is still Thing1 => Multiplier => Thing2. So it is not valid to call andThen(f2) on the result (f1partial) because the input type of function f2 (Thing2) is not the same as the output of the previous function (Multiplier => Thing2).
By contrast, f1.curried(_:Thing1).andThen(f2) expands to { x: Thing1 => f1.curried(x).andThen(f2) }. f1.curried(x) evaluates to type Multiplier => Thing2, like stated earlier, so you can call andThen(f2) on that, resulting in a Multiplier => Thing3. So then the entire expression evaluates to a Thing1 => Multiplier => Thing3
Perhaps it's more clear if you think about the differences between these two expressions:
val fcomposed1 = { x: Thing1 => f1.curried(x).andThen(f2) } // valid
val fcomposed2 = { x: Thing1 => f1.curried(x) }.andThen(f2) // error
I am learning currying in scala and trying to apply my knowledge on the following piece of code.
object excercise {
def sqrt2(input : Double) : ((Double, Double) => Double, Double) => Double = {
def iter(guessFxn : (Double, Double) => Double, initial : Double) : Double = {
if (isGoodEnough(initial)) initial
else {
val newGuess: Double = guessFxn(initial, input)
iter(guessFxn, newGuess)
}
}
iter
def isGoodEnough(guess: Double): Boolean = {
math.abs(guess * guess - input ) / input < 0.001
}
}
println(sqrt2(2) ( (g: Double, c: Double) => (g + c / g) / 2, 1))
}
What i want to achieve is that sqrt2 should return a function which takes as 2 arguments
1. fxn(that takes 2 doubles as arg and return a double val) 2. double val
When i am trying to run the worksheet it is giving me error
Error: missing arguments for method iter;
follow this method with `_' if you want to treat it as a partially applied function
iter
^
Error: type mismatch;
found : Unit
required: ((Double, Double) => Double, Double) => Double
}
^
Error: missing arguments for method iter;
follow this method with `_' if you want to treat it as a partially applied function
iter
^
You just have to inverse the order of those piece of codes:
iter
def isGoodEnough(guess: Double): Boolean = {
math.abs(guess * guess - input ) / input < 0.001
}
becomes:
def isGoodEnough(guess: Double): Boolean = {
math.abs(guess * guess - input ) / input < 0.001
}
iter
Indeed, ending with an inner declared method involves a return type of Unit...that's not what you want.
Besides, you had this advice:
follow this method with `_' if you want to treat it as a partially applied function
iter
because as explains before, iter method is not returned (since its call is not made at the end of the method) and thus compiler expects it to be executed.
Of course, to be executed, it needs its compulsory parameters, that you didn't provide.
So the compiler "thinks" that you expected to partially apply the function but badly. Note than a partially applied function is not the same concept than a partial function, that has a different meaning ... ).
It would allow to defer the call, and it's mostly used when dealing standard function (not curried), where we might need to provide only the first parameter and later the following.
Example of partially applied function:
def sum(i: Int, j: Int){...}
calls:
sum 1 _ //just the second parameter needs to be applied later.
sum _ //none parameter is specified, would need to specify both later.
sum 1 2 //complete call, not partially applied so
You can find a good use case of partially applied function here.
Note: this is a theoretical question, I am not trying to fix anything, nor am I trying to achieve any effect for a practical purpose
When creating a lambda in Scala using the (arguments)=>expression syntax, can the return type be explicitly provided?
Lambdas are no different than methods on that they both are specified as expressions, but as far as I understand it, the return type of methods is defined easily with the def name(arguments): return type = expression syntax.
Consider this (illustrative) example:
def sequence(start: Int, next: Int=>Int): ()=>Int = {
var x: Int = start
//How can I denote that this function should return an integer?
() => {
var result: Int = x
x = next(x)
result
}
}
You can always declare the type of an expression by appending : and the type. So, for instance:
((x: Int) => x.toString): (Int => String)
This is useful if you, for instance, have a big complicated expression and you don't want to rely upon type inference to get the types straight.
{
if (foo(y)) x => Some(bar(x))
else x => None
}: (Int => Option[Bar])
// Without type ascription, need (x: Int)
But it's probably even clearer if you assign the result to a temporary variable with a specified type:
val fn: Int => Option[Bar] = {
if (foo(y)) x => Some(bar(x))
else _ => None
}
Let say you have this function:
def mulF(a: Int, b: Int): Long = {
a.toLong * b
}
The same function can be written as lambda with defined input and output types:
val mulLambda: (Int, Int) => Long = (x: Int, y: Int) => { x.toLong * y }
x => x:SomeType
Did not know the answer myself as I never had the need for it, but my gut feeling was that this will work. And trying it in a worksheet confirmed it.
Edit: I provided this answer before there was an example above. It is true that this is not needed in the concrete example. But in rare cases where you'd need it, the syntax I showed will work.