Another Scala Newbie question.
Trying to find the difference between:
def _1_sumUntil(n: Int) = (f: Int => Int) => (0 to n).toList.foldLeft(0){(a,b) => a + f(b)}
and
def _2_sumUntil(n: Int)(f: Int => Int) = (0 to n).toList.foldLeft(0){(a,b) => a + f(b)}
what is the advantage of one over the other (if at all) ?
The first is a method with one parameter list that returns a function from Int => Int to Int, the second is a method with two parameter lists that returns an Int.
Technically, by means of what is called eta-expansion—a method can be transparently converted to a function value—, the second method can be partially applied, yielding the same function as the first method:
val a = _1_sumUntil(33) // (Int => Int) => Int
val b = _2_sumUntil(33) _ // (Int => Int) => Int via eta-expansion
My advise is to use the second variant and avoid explicit function values. The advantage of the second is that—unless you do use eta-expansion—no function value is instantiated (apart from the function passed to foldLeft) which is then applied. Also it is arguably easier to read.
I would use the first version only if the main purpose of the method is really to give you a function from Int => Int to Int to pass around.
See also this question and this question.
Related
This question relates to the scala course from coursera so I want to please ask you to not give me the plain solution that I can copy-paste as this would break the coursera honor code.
This relates to the second assignment.
def Set = Int => Boolean
As it can be seen, Set is a function which returns weather or not the given int is or not part of the set. This is plain and simple so far. However the task asks me to create a union
def union(f: Set, s: Set): Set = ???
This union should return a set that satisfies the condition of both sets.
How could I do something like this:
I thought that such a thing could be done by adding the functions together however the following code:
f + s
Will not compile properly as expected
My question to is:
How would I be able to create a function from 2 other functions?
x => if x == 0 true else false //first
x => if x == 1 true else false //second
And what should equal:
x => if x==0 || x == 1 true else false
I'm not asking for a solution but rather how would I go around building something like this?
As I think you already understand, these Sets are functions that test whether a value meets the criteria for each Set.
The union of such a Set must also be a function that returns a Boolean (as shown by the type signature)
def union(f: Set, s: Set): Set
which (because Set is a type alias) is equivalent to:
def union(f: Int => Boolean, s: Int => Boolean): Int => Boolean
In plain English, union of two sets A and B means: "is the item in A or B".
Your task is to write a function that carries out that plain English specification.
You cannot "add" two functions together (at least, not in a way that is applicable to this question), but you can combine their results.
The Set has form of Set = Int => Boolean. Given the Int function will return true if the value is in a Set.
Well if we want to create a singleton set, we will return new function, which will compare any value passed to it, with the one passed to the function that created it.
The union of two sets, is one set plus the other. It means the element you're looking for must be either in one or the other set. But how do we get the new set, well we return a new function that does just that - checks if an element is either in one set or another.
Remember that in Scala functions can return functions, which may be evaluated later. I think that's the key.
The Set is defined as a function from Int to Boolean, "summing" two Sets won't return a Set object, the union means that one element should be either in one or in the other set but always expressed as a function.
I hope this is not too much, but given an element it should satisfy either f or s.
First of all, it's type Set =. Not def. Set is a type alias not a function definition.
Now, your question. You need a function which, when given two Int =>Boolean combines them with OR and returns a Int => Boolean.
First, how would you do this for two Boolean arguments?
def or(a: Boolean, b: Boolean) = a || b
So now we're half way there. What we have:
A pair of Int => Boolean functions.
A function that takes two Booleans and return a Boolean.
So all we need to do is apply each Set to an Int to get a Boolean and OR the result. The confusion is probably here.
The easiest way to curry a function is to do it explicitly
def union(f: Set, s: Set): Set = {
def doUnion(x: Int) = //apply x to f and s, return OR
doUnion
}
But we can, in Scala, so this inline by declaring an anonymous function
def union(f: Set, s: Set): Set = x => //apply x to f and s, return OR
I'm learning Programming Paradigms in my University and reading this course material provided by the lecturer that defined a function this way:
val double = (x: Int) => 2 * x
double: Int => Int = <function1>
But from my own studies I found and got used to defining the same function like this:
def d (x: Int) = 2 * x
d: (x: Int)Int
I'm new to Scala. And both definitions give a result of:
res21: Int = 8
Upon passing 4 as the parameter.
Now my main question is why would the lecturer prefer to use val to define a function? I see it as longer and not really necessary unless using val gives some added advantages that I don't know of. Besides I understand using val makes some name a placeholder so later in the program, I could mistakenly write val double = 5 and the function would be gone!
At this stage I'm quite convinced I learned a better way of defining a function unless someone would tell me otherwise.
Strictly speaking def d (x: Int) = 2 * x is a method, not a Function, however scala can transparently convert (lift) methods into Functions for us. So that means you can use the d method anywhere that requires a Int => Int Function.
There is a small overhead of performing this conversion, as a new Function instance is created every time. We can see this happening here:
val double = (x: Int) => 2 * x
def d (x: Int) = 2 * x
def printFunc(f: Int => Int) = println(f.hashCode())
printFunc(double)
printFunc(double)
printFunc(d)
printFunc(d)
Which results in output like so:
1477986427
1477986427
574533740
1102091268
You can see when explicitly defining a Function using a val, our program only creates a single Function and reuses it when we pass as an argument to printFunc (we see the same hash code). When we use a def, the conversion to a Function happens every time we pass it to printFunc and we create several instances of the Function with different hash codes. Try it
That said, the performance overhead is small and often doesn't make any real difference to our program, so defs are often used to define Functions as many people find them more concise and easier to read.
In Scala, function values are monomorphic (i.e. they can not have type parameters, aka "generics"). If you want a polymorphic function, you have to work around this, for example by defining it using a method:
def headOption[A]: List[A] => Option[A] = {
case Nil => None
case x::xs => Some(x)
}
It would not be valid syntax to write val headOption[A]. Note that this didn't make a polymorphic function value, it is just a polymorphic method, returning a monomorphic function value of the appropriate type.
Because you might have something like the following:
abstract class BaseClass {
val intToIntFunc: Int => Int
}
class A extends BaseClass {
override val intToIntFunc = (i: Int) => i * 2
}
So its purpose might not be obvious with a very simple example. But that Function value could itself be passed to higher order functions: functions that take functions as parameters. If you look in the Scala collections documentation you will see numerous methods that take functions as parameters. Its a very powerful and versatile tool, but you need to get to a certain complexity and familiarity with algorithms before the cost /benefit becomes obvious.
I would also suggest not using "double" as an identifier name. Although legal Scala, it is easy to confuse it with the type Double.
What is the difference of the following two function definitions in Scala:
1) def sum(f: Int => Int)(a: Int, b: Int): Int = { <code removed> }
2) def sum(f: Int => Int, a: Int, b: Int): Int = { <code removed> }
?
SBT's console REPL gives different value for them so looks if they are somehow different:
sum: (f: Int => Int, a: Int, b: Int)Int
sum: (f: Int => Int)(a: Int, b: Int)Int
The first definition is curried, so that you can provide a and b at another time.
For instance, if you know the function you want to use in the current method, but don't yet know the arguments, you can use it so:
def mySum(v: Int): Int = v + 1
val newsum = sum(mySum) _
At this point, newsum is a function that takes two Ints and returns an Int.
In the context of summing it doesn't seem to make much sense; however, there have been plenty of times I've wanted to return different algorithms for parts of a program based upon something I know now, but don't know (or have access to) the parameters yet.
Currying buys you that feature.
Scala functions support multiple parameter lists to aid in currying. From your first example, you can view the first sum function as one that takes two integers and returns another function (i.e. curries) which can then take an Int => Int function as an argument.
This syntax is also used to create functions that look and behave as new syntax. For example, def withResource(r: Resource)(block: => Unit) can be called:
withResource(res) {
..
..
}
This question already has answers here:
How can I define an anonymous generic Scala function?
(2 answers)
Closed 9 years ago.
As most of you probably know you can define functions in 2 ways in scala, there's the 'def' method and the lambda method...
making the 'def' kind generic is fairly straight forward
def someFunc[T](a: T) { // insert body here
what I'm having trouble with here is how to make the following generic:
val someFunc = (a: Int) => // insert body here
of course right now a is an integer, but what would I need to do to make it generic?
val someFunc[T] = (a: T) => doesn't work, neither does val someFunc = [T](a: T) =>
Is it even possible to make them generic, or should I just stick to the 'def' variant?
As Randall Schulz said, def does not create a function, but a method. However, it can return a function and this way you can create generic functions like the identity function in Predef. This would look like this:
def myId[A] = (a: A) => a
List(1,2,3) map myId
// List(1,2,3)
List("foo") map myId
// List("foo")
But be aware, that calling myId without any type information infers Nothing. In the above case it works, because the type inference uses the signature of map, which is map[B](f: A => B) , where A is the type of the list and B gets infered to the same as A, because that is the signature of myId.
I don't believe it's possible. You can look at this previous post for more details:
How can I define an anonymous generic Scala function?
The only way around it (as one of the answers mentions) is to extend something like FunctionX and use a generic at the class level and then use that in the override of the apply function.
I don't believe it's possible either, but I'm a pessimist.
http://www.chuusai.com/2012/04/27/shapeless-polymorphic-function-values-1/
Edit:
Tell me if this isn't what you're asking, but this is why the accepted answer isn't what I thought you were asking for, see the link:
scala> :pa
// Entering paste mode (ctrl-D to finish)
def myId[A] = (a: A) => a
List(1,2,3) map myId
// List(1,2,3)
List("foo") map myId
// List("foo")
// Exiting paste mode, now interpreting.
myId: [A]=> A => A
res0: List[String] = List(foo)
scala> val f1 = myId[Int]
f1: Int => Int = <function1>
scala> val f2 = myId[String]
f2: String => String = <function1>
scala> List(1,2,3) map f2
<console>:10: error: type mismatch;
found : String => String
required: Int => ?
List(1,2,3) map f2
^
scala> List("foo") map f1
<console>:10: error: type mismatch;
found : Int => Int
required: String => ?
List("foo") map f1
^
The function values are not polymorphic, i.e., generic.
The closest thing is polymorphic functions I believe:
https://github.com/milessabin/shapeless#polymorphic-function-values
I am trying to figure out the issue, and tried different styles that I have read on Scala, but none of them work. My code is:
....
val str = "(and x y)";
def stringParse ( exp: String, pos: Int, expreshHolder: ArrayBuffer[String], follow: Int )
var b = pos; //position of where in the expression String I am currently in
val temp = expreshHolder; //holder of expressions without parens
var arrayCounter = follow; //just counts to make sure an empty spot in the array is there to put in the strings
if(exp(b) == '(') {
b = b + 1;
while(exp(b) == ' '){b = b + 1} //point of this is to just skip any spaces between paren and start of expression type
if(exp(b) == 'a') {
temp(arrayCounter) = exp(b).toString;
b = b+1;
temp(arrayCounter)+exp(b).toString; b = b+1;
temp(arrayCounter) + exp(b).toString; arrayCounter+=1}
temp;
}
}
val hold: ArrayBuffer[String] = stringParse(str, 0, new ArrayBuffer[String], 0);
for(test <- hold) println(test);
My error is:
Driver.scala:35: error: type mismatch;
found : Unit
required: scala.collection.mutable.ArrayBuffer[String]
ho = stringParse(str, 0, ho, 0);
^one error found
When I add an equals sign after the arguments in the method declaration, like so:
def stringParse ( exp: String, pos: Int, expreshHolder: ArrayBuffer[String], follow: Int ) ={....}
It changes it to "Any". I am confused on how this works. Any ideas? Much appreciated.
Here's a more general answer on how one may approach such problems:
It happens sometimes that you write a function and in your head assume it returns type X, but somewhere down the road the compiler disagrees. This almost always happens when the function has just been written, so while the compiler doesn't give you the actual source (it points to the line where your function is called instead) you normally know that your function's return type is the problem.
If you do not see the type problem straight away, there is the simple trick to explicitly type your function. For example, if you thought your function should have returned Int, but somehow the compiler says it found a Unit, it helps to add : Int to your function. This way, you help the compiler to help you, as it will spot the exact place, where a path in your function returns a non-Int value, which is the actual problem you were looking for in the first place.
You have to add the equals sign if you want to return a value. Now, the reason that your function's return value is Any is that you have 2 control paths, each returning a value of a different type - 1 is when the if's condition is met (and the return value will be temp) and the other is when if's condition isn't (and the return value will be b=b+1, or b after it's incremented).
class Test(condition: Boolean) {
def mixed = condition match {
case true => "Hi"
case false => 100
}
def same = condition match {
case true => List(1,2,3)
case false => List(4,5,6)
}
case class Foo(x: Int)
case class Bar(x: Int)
def parent = condition match {
case true => Foo(1)
case false => Bar(1)
}
}
val test = new Test(true)
test.mixed // type: Any
test.same // type List[Int]
test.parent // type is Product, the case class super type
The compiler will do its best to apply the most specific type it can based on the possible set of result types returned from the conditional (match, if/else, fold, etc.).