How is this type miss match? - scala

HI I am new at Scala Trying to run this code:
class Number(x : Int){
var number = x
def inc(): Int = {
number => number + 1
}
}
But I get the following error: solution.scala:12: error: missing parameter type
number => number + 1
I dont know how to fix this.

Essentially, you can expicitly say what type you're expect:
def inc(): Int = {
number: Int => number + 1
}
BUT this won't compile, cause what you've defined is function, so:
def inc(): (Int) => Int = {
// some function that takes Int, calls it `number` and increment
number: Int => number + 1
}
would be closer,
BUT
it doesn't make sense and notice, that number you've defined has nothing in common with number variable inside class
-- that's why Scala compiler cannot infer type for you.
I think you have wanted to write something like:
def inc(): Int = {number += 1; number;}
// will take effect on number field
or
def inc(num: Int): Int = num + 1

or simply:
def inc = (x: Int) => x + 1
since Int return type is inferred, no need to specify it
As for dealing with mutability in the question, inc(1), inc(5), etc. are themselves transformed representations of the number passed to the class instance (i.e. they equate to "var number", but immutably so). No real need for mutability based on what we see here...

Related

Scala anonymous function syntax and return type

I have found few kinds of anonymous function syntax in scala:
val m5_1 = { (n: Int) => n * 5 }
val m5_2 = (n: Int) => { n * 5 } : Int
val m5_3: Int => Int = n => { n * 5 }
Is that all types or some more syntax kinds present?
Are they all equivalent?
Which one is more/less preferred?
How can I specify the return type in m5_1 ?
I'll try to add to #pamu's answer:
Which one is more/less preferred?
I'd say the second variant is a bit uncommon. When the type inference is easily visible, you can go for the first, otherwise being explicit as in the third case is good. You don't need braces there, so a simpler variant is
val m5_3: Int => Int = n => n * 5
Or even
val m5_3: Int => Int = _ * 5
How can I specify the return type in m5_1 ?
The return type is Int => Int, so that is the same type annotation as you use in the third case:
val m5_1: Int => Int = { (n: Int) => n * 5 }
But then of course, you can let Scala use the type inference on the right hand side:
val m5_1: Int => Int = n => n * 5
And therefore this is identical to your third form.
Note that the : Int in the second form is not defining the type of m5_2, which is Int => Int and not Int. It simply tells Scala that the type of n * 5 is meant to be Int. This can aid you reading the code, but it doesn't actually change the way the type is inferred in this case. You can think of your second form of actually being:
val m5_2 = (n: Int) => {
val res = n * 5: Int // : Int redundant here because it is already inferred
res
}
Where val res = n * 5: Int has the same effect as val res: Int = n * 5
Is that all types or some more syntax kinds present ?
Lambda syntax requires the input parameter type to be known. If not compiler throws an error. In all the syntaxes you are trying to give this information. But return type can be inferred by the compiler.
Are they all equivalent?
All are equivalent
Which one is more/less preferred ?
The below one is recommended if you do not want to see explicit type annotation
val m5_1 = { (n: Int) => n * 5 }
How can I specify the return type in m5_1 ?
Return type is inferred from the last line of the lambda. The last line is n * 5 which of type Int. So, compiler infers the type for you. You can skip giving the type information explicitly
Well, the above answers have properly explained almost everything I guess. I just want to add one more variant that we could do here:
val m5_4 = {n=> n*5}:Int=>Int

Declare variable in Scala

I just new in Scala, I know Scala have three keywords to declare variables is:
def defines a method
val defines a fixed value (which cannot be modified)
var defines a variable (which can be modified)
I am going to write some code to test with an anonymous method.
object Anonymous {
def main(args: Array[String]): Unit = {
def double_1 = (i: Int) => { i * 2 }
val double_2 = (i: Int) => { i * 2 }
var double_3 = (i: Int) => { i * 2 }
println(double_1(2))
println(double_2(2))
println(double_3(2))
}
}
What is the difference about three ways above, when I use double_1, double_2, double_3?
What is the memory segment have to store the variables?
Thanks!
First off, they are not anonymous methods. They are functions and they each have a name so they are not anonymous.
The main difference between them is that double_3 can be reassigned to some different function value.
var double_3 = (i: Int) => { i * 2 }
double_3 = (i: Int) => i + 3 // the compiler allows this
The others cannot.
It would be rather unusual to defined a function as a def. def is mostly used to declare methods because a def is re-evaluated every time it is referenced.
def x = 3 + 4
val y = 3 + 4
Both x and y evaluate to 7, but the addition is redone every time x is referenced. For y the addition is done once, at the definition, and never again.

How to use function with Any input

I have to define a second order function that takes as a parameter a function.
In my application, the input function may have any input type, but the output type has to be a specified one (suppose Int, it does not matter).
I define the second order function has:
def sof(f : (Any => Int) ) = {...}
Now, if I have a function f : Int => Int, and I call:
sof(f)
I get:
found : Int => Int
required: Any => Int
I guess I am misunderstanding the meaning of the Any type.
How can I make it work?
The parameters of functions in Scala are contravariant. That means that Int => Int is not a subtype of Any => Int, but vice-versa. Imagine the following: You pass a String to the Any => Int function (that is actually implemented by a Int => Int function). How would the Int => Int handle the String argument?
You shouldn't use Any there, but a type parameter such as:
def sof[A](f: A => Int) = {...}
However I don't think you can do much with that method. Probably you would want something like this:
def sof[A](a: A)(f: A => Int) = f(a)
// usage example
val x = sof("hello")(_.size * 2) // the result is 10
// you can also partially apply it to obtain other functions
val sizeDoubler: String => Int = sof(_)(_.size * 2)
val helloDoubleSize = sizeDoubler("hello") // the result is 10
This way you can pass any type to sof plus you'll have the compiler by your side to signal any strange behaviour. Using Any you lose this ability.
Final Note: In case the syntax I used to pass two parameters (the A value and the A => Int function) to a method looks strange to you that's called currying. If you Google it you'll find many good articles about it.

Specifying the lambda return type in Scala

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.

how do I increment an integer variable I passed into a function in Scala?

I declared a variable outside the function like this:
var s: Int = 0
passed it such as this:
def function(s: Int): Boolean={
s += 1
return true
}
but the error lines wont go away under the "s +=" for the life of me. I tried everything. I am new to Scala btw.
First of all, I will repeat my words of caution: solution below is both obscure and inefficient, if it possible try to stick with values.
implicit class MutableInt(var value: Int) {
def inc() = { value+=1 }
}
def function(s: MutableInt): Boolean={
s.inc() // parentheses here to denote that method has side effects
return true
}
And here is code in action:
scala> val x: MutableInt = 0
x: MutableInt = MutableInt#44e70ff
scala> function(x)
res0: Boolean = true
scala> x.value
res1: Int = 1
If you just want continuously increasing integers, you can use a Stream.
val numberStream = Stream.iterate(0)(_ + 1).iterator
That creates an iterator over a never-ending stream of number, starting at zero. Then, to get the next number, call
val number: Int = numberStream.next
I have also just started using Scala this was my work around.
var s: Int = 0
def function(s: Int): Boolean={
var newS = s
newS = newS + 1
s = newS
return true
}
From What i read you are not passing the same "s" into your function as is in the rest of the code. I am sure there is a even better way but this is working for me.
You don't.
A var is a name that refers to a reference which might be changed. When you call a function, you pass the reference itself, and a new name gets bound to it.
So, to change what reference the name points to, you need a reference to whatever contains the name. If it is an object, that's easy enough. If it is a local variable, then it is not possible.
See also call by reference, though I don't think this question is a true duplicate.
If you just want to increment a variable starting with 3
val nextId = { var i = 3; () => { i += 1; i } }
then invoke it:
nextId()