One argument referencing another in the argument list - scala

Occasionally, I encounter one argument wanting to reference another. For instance,
def monitor(time: Double, f: Double => Double, resolution: Double = time / 10) = {...}
Note that resolution refers to time. Are there languages where this is possible? Is it possible in Scala?

It is somewhat possible in Scala, but you have to curry the parameters:
def monitor(time: Double, f: Double => Double)(resolution: Double = time / 10)
You cannot do it in the way the question is posed.

I don't know any langage where this construction is possible, but a simple workaround is not difficult to find.
In scala, something like this is possible :
scala> def f(i : Int, j : Option[Int] = None) : Int = {
| val k = j.getOrElse(i * 2)
| i + k
| }
f: (i: Int, j: Option[Int])Int
scala> f(1)
res0: Int = 3
scala> f(1, Some(2))
res1: Int = 3
In scala, you can also make something like this :
scala> def g(i : Int)(j : Int = i * 2) = i + j
g: (i: Int)(j: Int)Int
scala> g(2)(5)
res6: Int = 7
scala> g(2)()
res7: Int = 6

Related

How to access the replaceAllIn() counter?

I am using
val str2 = regex.replaceAllIn(str1, "other")
and need to count the number of replaces... There are a way retrieve the value of the internal replaceAllIn counter?
PS: this is usual in other languages (example), so I am supposing that Scala offer similar thing.
scala> val r = "x".r
r: scala.util.matching.Regex = x
scala> var i = 0
i: Int = 0
scala> r.replaceAllIn("xooxxox", m => { i += 1 ; "X" })
res0: String = XooXXoX
scala> i
res1: Int = 4
will do appendReplacement under the hood.
Takes another step but you could findAllIn and count the number found. Then do replaceAllIn.
scala> "foo".r.findAllIn("barbazfoobazfoo").size
res7: Int = 2

Scala: How to make a closure not to see changes in its free variable?

In the following code snippet, closure foo see the changes made in x as it should in scala. However, how can I make local variable y in foo hold value of x permanently and not see changes?
scala> var x = 10
x: Int = 10
scala> val foo = (a:Int) => {val y = x; a + y}
foo: Int => Int = <function1>
scala> foo(3)
res1: Int = 13
scala> x = 5
x: Int = 5
scala> foo(3) //see changes made in x. But how can I make closure not to see changes made on x?
res2: Int = 8
You could do something like this:
val foo = ((x:Int) => (a:Int) => {val y = x; a + y})(x)
In this case, x is bound in foo.
What you are doing is an example of closure.
scala> var x = 10
x: Int = 10
scala> val foo = { val y = x; (a: Int) => a + y }
foo: Int => Int = $$Lambda$1027/1344946518#5416f8db
scala> foo(3)
res0: Int = 13
scala> x = 5
x: Int = 5
scala> foo(3)
res1: Int = 13

sequence of scala function return methods

I am new to scala and learning scala.
scala> def first(x: Int)= (y: Int) => x + y
first: (x: Int)Int => Int
scala> val second= first(1)
second: Int => Int = <function1>
scala> second(2)
res8: Int = 3
I want to understand the above function, first 1 is passed as an argument and returns second function it does nothing , just stores the value of x=1 , then the second val, which represents the second function is called as 2, then the value of Y is stored as 2 , then it called the return => x + y,
which evaluates to 1+2 and gives 3 as result.
Please let me know if my understanding is correct.
If anyone can add something to it or correct if I am wrong.
Thanks and Regards,
scala> def first(x: Int)= (y: Int) => x + y // 1
first: (x: Int)Int => Int
scala> val second= first(1) // 2
second: Int => Int = <function1>
scala> second(2) // 3
res8: Int = 3
In case 1, you have created a function called first which accepts an integer and returns a function which accepts an integer and adds it to integer you passed to first.
In case 2, you apply 1 to the first function to return a function which accepts an integer and adds 1 to it. You have 'labelled' this function second. This is equivalent to (y : Int) => 1 + y.
In case 3, you apply 2 to the second function which returns 3 as expected.

Currying Example in Scala

Is the following a good example of currying?
def sum(a: Int, b: Int) : (Int => Int) = {
def go(a: Int) : Int = {
a + b;
}
go
}
I half understand the below results, but how could I write (or maybe how I should've written) sum() in a curried way?
scala> sum(3,4) res0: Int => Int = <function1>
scala> sum(3,4).apply(2) res1: Int = 6
scala> sum(3,4).apply(3) res2: Int = 7
Currying mechanism was introduced in Scala to support type inference. For example foldLeft function in the standard lib:
def foldLeft[B](z: B)(op: (B, A) => B): B
Without currying you must provide types explicitly:
def foldLeft[B](z: B, op: (B, A) => B): B
List("").foldLeft(0, (b: Int, a: String) => a + b.length)
List("").foldLeft[Int](0, _ + _.length)
There are three ways to write a curried function:
1) Write it in currying form:
def sum(a: Int)(b: Int) = a + b
which is just syntactic sugar for:
def sum(a: Int): Int => Int = b => a + b
2) Call curried on the function object (sum _).curried and check the types:
sum: (a: Int, b: Int)Int
res10: Int => (Int => Int) = <function1>
In your example, you can use Scala type inference to reduce the amount of code and change your code:
def sum(a: Int, b: Int) : (Int => Int) = {
def go(a: Int) : Int = {
a + b;
}
go
}
into:
def sum(a: Int, b: Int) : (Int => Int) = c => a + b + c
semantically these are the same, because you explicitly provided the return type, so Scala knows that you will return a function wich takes an Int argument and return an Int
Also a more complete answer about curring was given by retronym
In the lambda calculus, you have something called a lambda abstraction λx.term1 which when applied to another term (λx.term1)(term2), corresponds to the concept of applying a function to term2. The lambda calculus is the theoritical basis for functional programming. In lambda calculus, you don't have lambda abstraction taking multiple parameters. So how you do you represent functions of two arguments? The answer is to return a function that will take the other argument and then return the result on both argument.
So in Scala, if you have a var a in scope, you can return a function that will add its argument b to a:
scala> var a = 1
a: Int = 1
scala> val adda = (b: Int) => a + b
adda: Int => Int = <function1>
scala> adda(3)
res1: Int = 4
Now if you have an argument a in scope it works just as well:
scala> val sum = (a: Int) => (b: Int) => a + b
sum: Int => Int => Int = <function1>
scala> sum(3)(5)
res2: Int = 8
So without having access to a syntax that lets you define a function of two arguments, you just basically achieve that with a function sum taking an argument a returning a function equivalent to adda that takes a argument b and returns a + b. And that's called currying.
As an exercise, define a function using currying that will let you work on 3 arguments. For instance val sum3: Int => Int => Int => Int = ???, and fill in what goes into the question marks.
Disclaimer: I'm pretty new to Scala, so treat this with a grain of salt
In purely functional languages like Haskell currying plays very important role in function composition, e.g. if I want to find sum of squares I would write in Haskell (sorry for too much Haskell, but syntax has similarities with Scala and it's not that hard to guess)
without currying:
sum_of_squares xs = foldl (\x y -> x + y) 0 (map (\x -> x * x) xs)
with curring (. is a function composition):
sum_of_squares = (foldl (\x y -> x + y) 0) . (map (\x -> x * x))
which allows me to operate with functions instead of operating with arguments. It may not be that clear from previous example, but consider this:
sum_of_anything f = (foldl (\x y -> x + y) 0) . (map f)
here f is an arbitrary function and I can rewrite the first example as:
sum_of_squares = sum_of_anything (\x -> x * x)
Now let's go back to Scala. Scala is OO language, so usually xs will be a receiver:
def sum_of_squares(xs: List[Int]): Int = {
xs.map(x => x * x).foldLeft(0)((x, y) => x + y)
}
sum_of_squares(List(1,2,3))
def sum_of_anything(f: (Int, Int) => Int)(xs: List[Int]): Int = {
xs.map(x => x * x).foldLeft(0)(f)
}
sum_of_anything((x, y) => x + y)(List(1, 2, 3))
which means I can't omit xs. I can probably rewrite it with lambdas, but I won't be able to use map and foldLeft without adding more boilerplate. So as other people mentioned in Scala "currying" is probably mostly used to support type inference.
Meanwhile in your particular example I have a feeling that you don't need outer a, it's shadowed anyway, you probably meant:
def sum(b: Int) : (Int => Int) = {
def go(a: Int) : Int = {
a + b;
}
go
}
But in this simple example you can use partial application (given that you will probably pass sum to higher order functions):
List(1, 2, 3).map(sum(2)) //> res0: List[Int] = List(3, 4, 5)
List(1, 2, 3).map(_ + 2) //> res1: List[Int] = List(3, 4, 5)
For this kind of application sum can be shorter because sum(2) will be implicitly expanded to Int => Int:
def sum(b: Int)(a: Int): Int = a + b
This form is not valid for val sum2 = sum(2) though, you will have to write val sum2 = sum(2) _.

Simple question about tuple of scala

I'm new to scala, and what I'm learning is tuple.
I can define a tuple as following, and get the items:
val tuple = ("Mike", 40, "New York")
println("Name: " + tuple._1)
println("Age: " + tuple._2)
println("City: " + tuple._3)
My question is:
How to get the length of a tuple?
Is tuple mutable? Can I modify its items?
Is there any other useful operation we can do on a tuple?
Thanks in advance!
1] tuple.productArity
2] No.
3] Some interesting operations you can perform on tuples: (a short REPL session)
scala> val x = (3, "hello")
x: (Int, java.lang.String) = (3,hello)
scala> x.swap
res0: (java.lang.String, Int) = (hello,3)
scala> x.toString
res1: java.lang.String = (3,hello)
scala> val y = (3, "hello")
y: (Int, java.lang.String) = (3,hello)
scala> x == y
res2: Boolean = true
scala> x.productPrefix
res3: java.lang.String = Tuple2
scala> val xi = x.productIterator
xi: Iterator[Any] = non-empty iterator
scala> while(xi.hasNext) println(xi.next)
3
hello
See scaladocs of Tuple2, Tuple3 etc for more.
One thing that you can also do with a tuple is to extract the content using the match expression:
def tupleview( tup: Any ){
tup match {
case (a: String, b: String) =>
println("A pair of strings: "+a + " "+ b)
case (a: Int, b: Int, c: Int) =>
println("A triplet of ints: "+a + " "+ b + " " +c)
case _ => println("Unknown")
}
}
tupleview( ("Hello", "Freewind"))
tupleview( (1,2,3))
Gives:
A pair of strings: Hello Freewind
A triplet of ints: 1 2 3
Tuples are immutable, but, like all cases classes, they have a copy method that can be used to create a new Tuple with a few changed elements:
scala> (1, false, "two")
res0: (Int, Boolean, java.lang.String) = (1,false,two)
scala> res0.copy(_2 = true)
res1: (Int, Boolean, java.lang.String) = (1,true,two)
scala> res1.copy(_1 = 1f)
res2: (Float, Boolean, java.lang.String) = (1.0,true,two)
Concerning question 3:
A useful thing you can do with Tuples is to store parameter lists for functions:
def f(i:Int, s:String, c:Char) = s * i + c
List((3, "cha", '!'), (2, "bora", '.')).foreach(t => println((f _).tupled(t)))
//--> chachacha!
//--> borabora.
[Edit] As Randall remarks, you'd better use something like this in "real life":
def f(i:Int, s:String, c:Char) = s * i + c
val g = (f _).tupled
List((3, "cha", '!'), (2, "bora", '.')).foreach(t => println(g(t)))
In order to extract the values from tuples in the middle of a "collection transformation chain" you can write:
val words = List((3, "cha"),(2, "bora")).map{ case(i,s) => s * i }
Note the curly braces around the case, parentheses won't work.
Another nice trick ad question 3) (as 1 and 2 are already answered by others)
val tuple = ("Mike", 40, "New York")
tuple match {
case (name, age, city) =>{
println("Name: " + name)
println("Age: " + age)
println("City: " + city)
}
}
Edit: in fact it's rather a feature of pattern matching and case classes, a tuple is just a simple example of a case class...
You know the size of a tuple, it's part of it's type. For example if you define a function def f(tup: (Int, Int)), you know the length of tup is 2 because values of type (Int, Int) (aka Tuple2[Int, Int]) always have a length of 2.
No.
Not really. Tuples are useful for storing a fixed amount of items of possibly different types and passing them around, putting them into data structures etc. There's really not much you can do with them, other than creating tuples, and getting stuff out of tuples.
1 and 2 have already been answered.
A very useful thing that you can use tuples for is to return more than one value from a method or function. Simple example:
// Get the min and max of two integers
def minmax(a: Int, b: Int): (Int, Int) = if (a < b) (a, b) else (b, a)
// Call it and assign the result to two variables like this:
val (x, y) = minmax(10, 3) // x = 3, y = 10
Using shapeless, you easily get a lot of useful methods, that are usually available only on collections:
import shapeless.syntax.std.tuple._
val t = ("a", 2, true, 0.0)
val first = t(0)
val second = t(1)
// etc
val head = t.head
val tail = t.tail
val init = t.init
val last = t.last
val v = (2.0, 3L)
val concat = t ++ v
val append = t :+ 2L
val prepend = 1.0 +: t
val take2 = t take 2
val drop3 = t drop 3
val reverse = t.reverse
val zip = t zip (2.0, 2, "a", false)
val (unzip, other) = zip.unzip
val list = t.toList
val array = t.toArray
val set = t.to[Set]
Everything is typed as one would expect (that is first has type String, concat has type (String, Int, Boolean, Double, Double, Long), etc.)
The last method above (.to[Collection]) should be available in the next release (as of 2014/07/19).
You can also "update" a tuple
val a = t.updatedAt(1, 3) // gives ("a", 3, true, 0.0)
but that will return a new tuple instead of mutating the original one.