Calling Method inside a method giving a type mismatch error Scala - scala

So I'm trying to call a method("Mean") from inside another method("Centre"), it's giving a type mismatch error.
But if I execute the method("Mean") seperately and store it's result in some variable and then execute method("Centre") using the variable instead of method("Mean"), it works.
Can anyone please explain why?
val X = Vector(3.0,4,5)
val Y = Vector(6,9.0,15)
type D = Double
type V = Vector[D]
def Mean (v:V)= v.sum/v.length
val meanX = Mean(X)
def Centre (v:V) = v.map(X => X - Mean(X))
Centre(X)
Error:
command-1723108043672149:8: error: type mismatch;
found : D
(which expands to) Double
required: V
(which expands to) scala.collection.immutable.Vector[Double]
def Centre (v:V) = v.map(X => X - Mean(X))
but it works if I use "meanX" instead of "Mean(X):
Centre: (v: V)scala.collection.immutable.Vector[Double]
res36: scala.collection.immutable.Vector[Double] = Vector(-1.0, 0.0,1.0)

Mean() is defined to take an argument of type V (i.e. Vector[Double]) but in this code, v.map(X => X - Mean(X)) you're trying to pass a Double value instead, because you have redefined the variable X. Thus the error.
I think what you want to do is v.map(n => n - Mean(X)) or, better yet, v.map(_ - Mean(X)). That way X has only one meaning.

Related

In scala not declared value has no error. How does it works?

Hi I'm newbie in scala.
when I write the below code, Even I didn't declared variable y, but it is allowed.
object exercise {
def fixedPoint(f: Double => Double)(firstGuess: Double) = {
//some code
}
def sqrt(x: Double) = fixedPoint(y => x / y)(1) //No error. weird...
}
I don't understand how does it works?
I didn't declared variable y
Actually, you did.
This ...
y => ...
... translates into, "Here's a function that takes a single argument. I'm going to call that argument y."
When you declare f: Double => Double, it means that function f will take Double as input parameter and will return Double as output. So, when you pass y => x / y function, y here is of type Double and x/y(output) is of type double.
It is not giving any compiler error because compiler can infer the type based on type of function fixedPoint expects.
Suggest you have a look for How to use function literals (anonymous functions) in Scala.
In the post, it use a simple example (i: Int) => i % 2 == 0 to act as a function literals, and pass it to the function filter. And see follows:
Because the Scala compiler can infer from the expression that i is an Int, the Int declaration can be dropped off: val evens = x.filter(i => i % 2 == 0)
Then, this is exactly the situation in your post for y => x / y, the Double was dropped off in your code as scala compiler can infer from the expression.
Before I answer this question let me modify your code as:
object exercise {
def fixedPoint(f: Double => Double)(firstGuess: Double) = {
f(firstGuess) //call the function in f with the curried parameter
}
def sqrt(x: Double) = fixedPoint(y => x / y)(1) //No error. weird...
}
I have added a line to call function f (which takes Double and returns Double) with firstGuess parameter.
f(firstGuess) //call the function in f with the curried parameter
Let's see what what sqrt function is all about
def sqrt(x: Double) = fixedPoint(y => x / y)(1)
It takes a x and invokes fixedPoint with y => x/y and 1
now your y is firstGuess parameter (as per modified code) and x is the sqrt parameter.

How to use scala type lambda

With the following code,
val x: ({type X[Y] = Function1[Y, Unit]})#X = (y: Int) =>println(y)
It successfully compiles, but how could I use it? When I call it with x(1)
An compiling occurs that complains Type mismatch, Y expected: Y accutal: Int
You can't have a value of a type like ({type X[Y] = Function1[Y, Unit]})#X, just as you can't have a value of type Option or Function1. The only thing you can do with it is to apply it to a parameter, or to use it as a type argument for another type/method, which will eventually apply it to some parameters.

Putting two placeholders inside flatMap in Spark Scala to create Array

I am applying flatMap on a scala array and create another array from it:
val x = sc.parallelize(Array(1,2,3,4,5,6,7))
val y = x.flatMap(n => Array(n,n*100,42))
println(y.collect().mkString(","))
1,100,42,2,200,42,3,300,42,4,400,42,5,500,42,6,600,42,7,700,42
But I am trying to use placeholder "_" in the second line of the code where I create y in the following way:
scala> val y = x.flatMap(Array(_,_*100,42))
<console>:26: error: wrong number of parameters; expected = 1
val y = x.flatMap(Array(_,_*100,42))
^
Which is not working. Could someone explain what to do in such cases if I want to use placeholder?
In scala, the number of placeholders in a lambda indicates the cardinality of the lambda parameters.
So the last line is expanded as
val y = x.flatMap((x1, x2) => Array(x1, x2*100, 42))
Long story short, you can't use a placeholder to refer twice to the same element.
You have to use named parameters in this case.
val y = x.flatMap(x => Array(x, x*100, 42))
You can only use _ placeholder once per parameter. (In your case, flatMap method takes single argument, but you are saying -- hey compiler, expect two arguments which is not going to work)
val y = x.flatMap(i => Array(i._1, i._2*100,42))
should do the trick.
val y = x.flatMap { case (i1, i2) => Array(i1, i2*100,42) }
should also work (and probably more readable)

Function parameters evaluation in Scala (functional programming)

please find below a piece of code from Coursera online course (lecture 2.3) on functional programming in Scala.
package week2
import math.abs
object lecture2_3_next {
def fixedPoint(f: Double => Double)(firstGuess: Double): Double = {
val tolerance = 0.0001
def isCloseEnough(x: Double, y: Double): Boolean = abs((x - y) / x) / x < tolerance
def iterate(guess: Double): Double = {
val next = f(guess)
if (isCloseEnough(guess, next)) next
else iterate(next)
}
iterate(firstGuess)
}
def averageDamp(f: Double => Double)(x: Double): Double = (x + f(x)) / 2
def sqrt(x: Double): Double = fixedPoint(averageDamp(y => x / y))(1)
sqrt(2)
}
A few points blocked me while I'm trying to understand this piece of code.
I'd like your help to understanding this code.
The 2 points that annoying me are :
- when you call averageDamp, there are 2 parameters 'x' and 'y' in the function passed (eg. averageDamp(y => x / y)) but you never specify the 'y' parameter in the definition of the averageDamp function (eg. def averageDamp(f: Double => Double)(x: Double): Double = (x + f(x)) / 2). Where and how do the scala compiler evaluate the 'y' parameter.
- second point may be related to the first, I don't know in fact. When I call the averageDamp function, I pass only the function 'f' parameter (eg. y => x / y) but I don't pass the second parameter of the function which is 'x' (eg. (x: Double) second parameter). How the scala compiler is evaluating the 'x' parameter in this case to render the result of the averageDamp call.
I think I missed something about the evaluation or substitution model of scala and functional programming.
Thank's for your help and happy new year !
Hervé
1) You don't pass an x and an y parameter as f, you pass a function. The function is defined as y => x / y, where y is just a placeholder for the argument of this function, while x is a fixed value in this context, as it is given as argument for the sqrt method (in the example x is 2). Instead of the fancy lambda-syntax, you could write as well
def sqrt(x: Double): Double = fixedPoint(averageDamp(
new Function1[Double,Double] {
def apply(y:Double):Double = x / y
}
))(1)
Nothing magic about this, just an abbreviation.
2) When you have a second parameter list, and don't use it when calling the method, you do something called "currying", and you get back a partial function. Consider
def add(x:Int)(y:Int) = x + y
If you call it as add(2)(3), everything is "normal", and you get back 5. But if you call add(2), the second argument is still "missing", and you get back a function expecting this missing second argument, so you have something like y => 2 + y
The x is not a parameter of the (anonymous) function, it is a parameter of the function sqrt. For the anonymous function it is a bound closure.
To make it more obvious, let's rewrite it and use a named instead of an anonymous function:
def sqrt(x: Double): Double = fixedPoint(averageDamp(y => x / y))(1)
will can be rewritten as this:
def sqrt(x: Double): Double = {
def funcForSqrt(y: Double) : Double = x / y // Note that x is not a parameter of funcForSqrt
// Use the function fundForSqrt as a parameter of averageDamp
fixedPoint(averageDamp(funcForSqrt))(1)
}

Can't use a negative number in named parameters in Scala

I'm using Scala 2.11.2.
If I have this Fraction class:
case class Fraction(numerator: Int, denominator: Int) {}
Then this gives an error:
val f = new Fraction(numerator=-1, denominator=2)
But this is not:
val f = new Fraction(-1, denominator=2)
The error message is:
Multiple markers at this line
- not found: value
numerator
- not found: value
numerator
I tried to use negative numbers in other snippets with the same result, but the documentation doesn't mentions that this is not possible.
Am I doing something wrong?
Thanks
You need a space between the = and the -, or you can wrap the -1 in parentheses, otherwise the compiler gets confused. This is because =- is a valid method name, so the compiler cannot tell whether you are assigning a value to a named parameter, or making a method call.
so this gives an error:
val f = Fraction(numerator=-1, denominator=2)
but this is OK:
val f = Fraction(numerator = -1, denominator = 2)
and so is this:
val f = Fraction(numerator=(-1), denominator=2)