What do these lines mean (Scala / JavaTokenParsers)? - scala

I am trying to better understand how to do mass parsing/interpreting.
I am having difficulty understanding lines like these:
type L = () => Long
And then later there are other lines like
val term = chainl1(myNum, "[*/]".r ^^ {
case "*" => (u1:L, u2:L) => () => u1() * u2()
case "/" => (u1:L, u2:L) => () => u1() / u2()
})
I am just trying to understand the underlying structure here. What exactly is () here? What is the logical flow of these val statements?
I assume this means "if we find * or / in myNum, match on these two cases depending on which one it is, and then... long flow of logic I don't understand"

type L = () => Long
describes a function with zero arguments and return type Long. For example
def someConstant() = 5L
Here someConstant is of type L.
This line
case "*" => (u1:L, u2:L) => () => u1() * u2()
will return you a function of type Function2 (arity 2) with return type Function0(arity 0) which when is called will return the result of u1() * u2().
val f = () => (x:Int) => x
can be written as
() => ((x: Int) => x)
Here f is a function with arity 0 which when is called returns another function with arity 1 which accepts Int argument and returns it when called.
f()(6) == 6
is true statement.

The answer of ka4ell is correct, but does not mention why you would use () => Long instead of just using Long: with () => Long or L the execution of the calculation which returns the Long is delayed. We only execute the functions at the moment we want the actual result, this is called lazy evaluation.
In your case:
case "*" =>
// Return a function which takes two Ls : u1 and u2
// and which returns an L : () => u1() * u2()
(u1:L, u2:L) => () => u1() * u2()
Let's define a simple function which returns an L :
// return a function which will return a Long
// this could potentially be a very expensive calculation
def giveMeAnL(n: Long) = () => {
println("giveMeAnL is called")
n
}
If we would use an analogous function than the one in the case:
// analogous case "*" => ...
def multiply(u1:L, u2:L) = () => {
println("multiply is called")
u1() * u2()
}
// create two Ls
val (l1, l2) = (giveMeAnL(5L), giveMeAnL(2L))
val productL = multiply(l1, l2) // productL is of type L
The value productL now contains an L which can calculate the product of the two values. At this point, neither the product nor the two values are calculated. If we call the productL value, the two values are calculated and the product of these values is calculated.
val product = productL()
// multiply is called
// giveMeAnL is called
// giveMeAnL is called
// product: Long = 10
If somewhere in your parsing steps, you want to ignore some L values, the results of these Ls are never calculated, which improves the performance.
case "multiply first with 5" =>
(u1:L, u2:L) => () => u1() * 5L // u2 is never executed

If we split the line case "*" => (u1:L, u2:L) => () => u1() * u2():
case "*" => means match * to the code that is written next
(u1:L, u2:L) => {} is a definition of function that has two arguments of type L
u1 and u2 are functions, because their type is L, and it is actually () => Long which means this is a function that takes nothing and returns Long
() => u1() * u2() is a function with no arguments, that calls u1 and u2 and multiplies their results
Going back:
(u1:L, u2:L) => () => u1() * u2() is a function of two arguments which returns a function of no arguments, that executes both arguments of a first function, multiplies them and return the result
So, () => means a function with no arguments. The only exception here is case * => where => doesn't belong to a function, but rather to match statement

Related

scala differences between 2 functions syntaxes

I'm trying to understand the differences between these 2 syntaxes in scala and why they have not the same result.
testVal
and
testVal2
are not defined in the same way
object FunctionVsVal2 extends App {
val testVal: () => Int = {
val r = util.Random.nextInt
() => r
}
val testVal2: () => Int = () => {
val r = util.Random.nextInt
r
}
println(testVal())
println(testVal())
println(testVal2())
println(testVal2())
}
Thanks
testVal2 is a lambda expression. Each time you call testVal2(), it evaluates
{
val r = util.Random.nextInt
r
}
and so returns a new value.
testVal is a block expression. It calculates r first and then returns () => r (the last expression in the block), so each time you call testVal(), the same r is used.

missing parameter type for expanded function (Scala)

Here's my function:
def sumOfSquaresOfOdd(in: Seq[Int]): Int = {
in.filter(_%2==1).map(_*_).reduce(_+_)
}
Why am I getting the error "missing parameter type for expanded function"?
map is accepting function with one parameter ((A) => B) while every _ placeholder represents a separate parameter of anonymous function (i.e. _ * _ is function with two parameters). You can use i => i * i lambda for your map function:
def sumOfSquaresOfOdd(in: Seq[Int]): Int = {
in.filter(_%2==1)
.map(i => i * i)
.reduce(_ + _)
}
Also you can use sum instead of reduce(_ + _) (note that sum will not throw for empty sequences while reduce will):
def sumOfSquaresOfOdd(in: Seq[Int]): Int = {
in.filter(_%2==1)
.map(i => i * i)
.sum
}
I guess because map wants a function of a single argument, and you ask it to call * with two arguments. Replace _ * _ with arg => arg * arg and retry.
"map" was called with a function with two parameters when it is expecting a function of one parameter. There's another small bug due to the use of "reduce" - it throws an exception if there aren't any odd Ints in the input Seq.
A better solution would be:
def sumOfSquaresOfOdd(in: Seq[Int]): Int =
in.filter(_ % 2 == 1) . map(x => x * x) . sum
You must be using Scala2. Scala3 gives a much better error message:
Error:
2 | in.filter(_%2==1).map(_*_).reduce(_+_)
| ^^^
| Wrong number of parameters, expected: 1
(Edited to reflect changes in the other answers to this question.)

Composing a sequence of functions that return future

I am looking for an elegant way of composing a sequence of functions that return Future. I.e., for a sequence of (f1, f2, ..., f_n), each function being of type T=>Future[T], I want to produce a new function, g, where g(x) = f_n(...f2(f1(x))...).
My implementation is as follows:
def doInOrder[T] (fs : (T => Future[T])*)(implicit ec:ExecutionContext): T=>Future[T] = {
(t:T) => {
fs.reduceLeft((future1: T=>Future[T], future2: T=>Future[T]) =>
(arg:T) => future1(arg).flatMap((arg2:T) => future2(arg2))
)(t)
}
}
This works, as far as I can tell. The solution seems a little convoluted though, with a number of nested lambdas. Can it be simplified?
The problem comes from Horstmann's book, Scala for the impatient, which asks to
Write a function doInOrder that, given two functions f: T =>
Future[U] and g: U
=> Future[V], produces a function T => Future[U] that, for a given t, eventually yields g(f(t))
and then to:
Repeat the preceding exercise for any sequence of functions of type T
=> Future[T].
How about this?
def doInOrder[T] (fs : (T => Future[T])*)(implicit ec:ExecutionContext): T=>Future[T] = {
t => fs.foldLeft(Future.successful(t))((acc, f) => acc.flatMap(f))
}

Scala partial application via underscore when composing function literals

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

some operator questions

I'm new to scala so sorry if this is easy but I've had a hard time finding the answer.
I'm having a hard time understanding what <- does, and what ()=> Unit does. My understanding of these is that -> is sometimes used in foreach, and that => is used in maps. Trying to google "scala "<-" doesn't prove very fruitful. I found http://jim-mcbeath.blogspot.com/2008/12/scala-operator-cheat-sheet.html but it wasn't as helpful as it looks at first glance.
val numbers = List("one", "two", "three","four","five")
def operateOnList() {
for(number <- numbers) {
println(number + ": came out of this crazy thing!")
}
}
def tweener(method: () => Unit) {
method()
}
tweener(operateOnList)
() => Unit means that method is a function that takes no parameter and returns nothing (Unit).
<- is used in the for comprehension as an kind of assignation operator. for comprehension are a little bit specific because they are internally transformed. In your case, that would be transforms as numbers.foreach(i => println(i + ": came out of this crazy thing!"))
<- in the for comprehension means that we will iterate over each element of the numbers list and passed to number.
'<-' could be threated as 'in' so
for(number <- numbers){
...
}
could be translated into english as for each number in numbers do
'<-' has a twin with a different semantics: '->'. Simply it is just a replacement of comma in tuples: (a,b) is an equivalent to (a->b) or just a->b. The meaning after this symbols is that 'a' maps to 'b'. So this is often used in definition of Maps:
Map("a" -> 1,"aba" -> 3)
Map("London" -> "Britain", "Paris" -> "France")
Here you can think about mapping as a projection (or not) via some function (e.g. 'length of string', 'capital of').
Better explanation is here.
Last, but not least is '=>' which is map too, but with a general semantics. '=>' is in use all over the place in anonymous expressions:
scala> List(1,2,3,4).map(current => current+1)
res5: List[Int] = List(2, 3, 4, 5)
Which is for each element map current element of list with function 'plus one'
List(1,2,3,4).map(c => c%2 match {
| case 0 => "even"
| case 1 => "odd"
| }
| )
res6: List[java.lang.String] = List(odd, even, odd, even)
Map current element with provided pattern mathing
In the method
def tweener(method: () => Unit) {
method()
}
the method is called tweener, the parameter is arbitrarily named method, and the type of method is () => Unit, which is a function type, as you can tell from the =>.
Unit is a return type similar to void in Java, and represents no interesting value being returned. For instance, the return type of print is Unit. () represents an empty parameter list.
Confusingly, () is also used to represent an instance of Unit, called the unit value, the only value a Unit can take. But this is not what it means in the function type () => Unit, just as you can't have a function type 42 => Unit.
Back to your example, tweener takes a function of type () => Unit. operateOnList is a method, but it gets partially applied by the compiler to turn it into a function value. You can turn methods into functions yourself like this:
scala> def m = println("hi")
m: Unit
scala> m _
res17: () => Unit = <function0>
operateOnList can be turned into the right type of function because its parameter list is empty (), and its return type is implicity Unit.
As a side-note, if operateOnList were defined without the empty parameter list (as is legal, but more common when the return type is not Unit), you would need to manually partially apply it, else its value will be passed instead:
def f1() {}
def f2 {}
def g(f: () => Unit) {}
g(f1) // OK
g(f2) // error, since we're passing f2's result (),
// rather than partial function () => Unit
g(f2 _) // OK