I have this method:
def myMethod(value:File,x: (a:File) => Unit) = {
// Some processing here
// More processing
x(value)
}
I know I can call this as:
myMethod(new File("c:/"),(x:File) => println(x))
Is there a way I could call it using braces? Something like:
myMethod(new File("c:/"),{ (x:File) =>
if(x.toString.endsWith(".txt")) {
println x
}
})
Or do I have to write that in another method and pass that to myMethod?
The body part of the function can be a block enclosed in braces:
myMethod(new File("c:/"), x => {
if (x.toString.endsWith(".txt")) {
println(x)
}
})
An alternative is way to define myMethod as a curried function:
def myMethod(value: File)(x: File => Unit) = x(value)
Now you can write code like the following:
myMethod(new File("c:/")) { x =>
if (x.toString.endsWith(".txt")) {
println(x)
}
}
The example you gave actually works, if you correct the lack of parenthesis around x in println x. Just put the parenthesis, and your code will work.
So, now, you might be wondering about when you need parenthesis, and when you don't. Fortunately for you, someone else has asked that very question.
Related
I am trying to debug a Scala program (this is a build.sbt, but the question is not particular for sbt), where I need to give a partial function for a certain sbt setting. The value for the partial function looks like this
{
case Regex1(a,b,c) =>
case Regex2(d,e,f) =>
...
}
The partial function does not do what I want, so I wanted to debug it. Because I don't know exactly what is passed in, I want to capture the value that is passed into the partial function, but I don't know how to do that.
I could add a case a => println(a) at the beginning of the partial function, but this breaks the whole function.
You can do this:
val print: PartialFunction[InputType, InputType] = { case i => println(i); i }
print andThen {
case Regex1(a,b,c) => ...
case ...
}
I finally figured out how to do it. It is not very elegant, so if anyone knows of a better way, please add another answer!
The solution is to create the partial function explicitly as value:
val result = new PartialFunction[InputType,ResultType] {
def apply(value: InputType) = {
println("input is: " + value) // Yay, I captured the value
value match {
// Same as above
}
}
def isDefinedAt(value: InputType) = true
}
result
Another option would be to match all, and add another match that does the actual work:
{
case value => {
println(value)
value match {
// the original partial function
...
// you might need to add a catch-all that
// does nothing or returns a default value
case _ => None
}
}
}
def fun(f: Int => Unit) {
f(10)
f(20)
}
println("method 1 call:")
fun(i => {println("hi"); println(i)})
println("method 2 call:")
fun{println("hi"); println(_)}
The output is:
E:\test\scala>scala i.scala
method 1 call:
hi
10
hi
20
method 2 call:
hi
10
20
I think i => {println("hi"); println(i)} and println("hi"); println(_) are the same. Because we have one parameter and the parameter is used just once, we can use _ to simplify the code.
Then, why does method 2 just print "hi" once?
(Does it mean: if I want to use _ to simple the calling, the contents on the right of => just can have one expression, if have more than one, e.g. println("hi"); println(i); Then, we can not use _ to replace?
println(_) expands to x => println(x), so {println("hi"); println(_)} expands to {println("hi"); x => println(x)}. So when fun{println("hi"); println(_)} executes, the following steps take place:
The expression {{println("hi"); println(_)}} is evaluated. Which means:
println("hi") is evaluated and then
x => println(x) is evaluated, creating a function object that will print its argument.
The thus-created function object is the result of the expression.
The method func is called with the created function object as its argument. func will call the function with 10 and 20, causing it to print those numbers.
First, you have to know that in scala { block; of; code } is an expression that evaluates to whatever the last expression inside it evaluates to.
When you say:
fun(i => { println("hi"); println(i) })
you create an anonymous function, which body contains 2 expressions, both returning () and both are evaluated when function is called, everything as expected.
But when you say
fun({println("hi"); println(_)})
You pass in a block, not an anonymous function. As sepp2k explained this expands to
{ println("hi"); x => println(x) }
So, you pass a block to fun, this block is being evaluated before it is passed. So first println("hi") happens, it is printed just once as block is evaluated once, and then this x => println(x) is evaluated, which is a function Int => Unit, that prints its argument. This, and only this (as a last expression is passed to the fun. This is why each time you call fun it just prints the argument twice.
To see further on how block could work you can look at this example that does more in the block
fun {
println("building the function")
val uuidOfThisFunction = UUID.randomUUID
x => println(s"$uuidOfThisFunction, $x")
}
So this block prepares a function giving it some extra context through the closure. This uuid will stay the same for both calls that happen if fun.
building the function
86e74b5e-83b5-41f3-a71c-eeafcd1db2a0, 10
86e74b5e-83b5-41f3-a71c-eeafcd1db2a0, 20
The example that would look more like what you did with first call would be
fun(
x => {
println("calling the function")
val uuidOfThisCall = UUID.randomUUID
println(s"$uuidOfThisCall, $x")
}
)
The block evaluates every time f is called.
calling the function
d3c9ff0a-84b4-47a3-8153-c002fa16d6c2, 10
calling the function
a0b1aa5b-c0ea-4047-858b-9db3d43d4983, 20
In scala we can use for loops as follows:
for { a <- someCollection
b = a.someFunc} //inbody we can use b
I need similar functionality with a while loop for example:
while({ val a = someFunction
a.isDefined }) { //do something with a in body }
How can I do this in scala?
EDIT
I know we can do this using a var on top and modifying it within the loop but I was looking for something more elegant.
What I wish to accomplish is as follows. The function someFunction iterates over a collection of Options and check for the item that is not a None. If it does not find such an option it returns a None. I can probably do this using
for( a <- myCollection
if a.isDefined) {}
but in this case I dont make use of my function.
You could write your own extended while function, like:
def extendedWhile[T](condFunc: => Option[T])(block: T => Unit): Unit = {
val a = condFunc
if (a.isDefined) {
block(a.get)
extendedWhile(condFunc)(block)
}
}
Which can be used as:
def rand =
if ((new scala.util.Random).nextFloat < 0.4) None
else Some("x")
extendedWhile(rand) {
x => println(x)
}
// prints out x a random amount of times
This extendedWhile function is tail recursive, so it should normally be as performant as the regular while loop.
I am not sure I like this, but one way to do this is to define the variable as 'var' outside the loop.
var a: Boolean = _;
def someFunction: Boolean = true
while({ a = someFunction; a }) {
println("hi " + a)
}
For is actually syntactic sugar for foreach, map, and flatMap.
So your code above desugars to:
someCollection.map { a=> f(a)}.foreach {b => ... //something using b}
Now, while is not a desugaring, but an actual imperative syntactic construct.
So the best you can do is
var a = true
while (a) {
a = someFunction (a)
}
In practice I never find myself using while, and instead use higher-order functions: like
input.takeWhile(_ != '').foreach { //do something }
Suppose I'm writing a GUI
class Kitteh (val age: Int) {
require (age < 5)
def saveMeow(file: File) = { /* implementation */ }
def savePurr(file: File) = { /* implementation */ }
}
The frame has a field for the current Kitteh, which is an Option because it might not have been defined yet, or the user may have attempted to create an invalid one:
var currentKitteh: Option[Kitteh] = None
Now I want to create a Kitteh safely when the user hits Create
val a = ... // parse age from text box
currentKitteh = try { Some(new Kitteh(a)) } catch { case _ => None }
My GUI has two buttons which do similar things. In psedocode, they should both
if (currentKitteh.isDefined) {
if (file on the disk already exists) {
bring up a dialog box asking for confirmation
if (user confirms)
<< execute method on currentKitteh >>
}
}
else bring up warning dialog
Don't worry about the detail: the point is that because there is code duplication, I want to create a common method that I can call from both buttons. The only difference is the method on the Kitteh that needs to be executed.
Now if currentKitteh were not an Option, the common method could have a signature like
def save(filename: String, f:(File => Unit)) {
which I could call with, for example
save("meow.txt", currentKitteh.saveMeow _)
but since it is actually an Option, how could I implement this?
I could just check whether currentKitteh is defined, and do a .get before calling the save method for each button, but is there another way, leaving this check in the save method? In other words, given an Option[A], is it possible to specify a partial function from a method on the (possibly non-existent) A object?
(hope this question makes sense, convoluted example notwithstanding)
edit: Bonus question: what if, instead of Option[Kitteh], I used Either[Throwable, Kitteh]?
update: Additional line added to pseudocode to bring up warning dialog: ideally, the save method should always be called so that the user is warned if there is no valid Kitteh to save.
This looks like the best option to me:
currentKitteh foreach { c => save("meow.txt", c.saveMeow _) }
If you're repeatedly doing this, you can abstract it,
def currentSaveMeow(file: String) = currentKitteh foreach { c =>
save(file, c.saveMeow _)
}
currentSaveMeow("meow.txt")
I suppose to answer your original question, you could also push the logic into the function argument,
save("meow.txt", file => currentKitten.foreach(_.saveMeow(file)))
The semantics are a little different with this version.
Update. If k: Option[Kitteh] is replaced by k: Either[Throwable, Kitteh], then what about k.right foreach { c => ... }? You could also use k.right map ... if you want to preserve error information.
In response to the modified question, here's another abstraction possibility,
def save(filename: String, f: (Kitteh, File) => Unit)
Now save has the responsibility of unpacking currentKitteh. Call save like this,
save("meow.txt", (k, f) => k.saveMeow(f))
or like this,
save("meow.txt", _ saveMeow _)
You can map a function to it and getOrElse your fail function:
def save =
o map {s => () => "saved a kitteh! " + s} getOrElse {() => "oh noes, no kittehs!"}
then you just:
save()
You could define a class BadKitteh and have that produce error messages. Then simply use currentKitty.getOrElse(badKitty) if you need one.
I have this weird situation that I don't understand. I'm reading "Programming in Scala" book, Ch. 9.
Let's say I have a curried function:
def withThis(n:Int)(op:Int=>Unit){
println("Before")
op(n);
println("After")
}
When I call it with one argument inside a special curly-syntax it works as expected:
withThis(5){
(x) => {println("Hello!"); println(x); }
}
// Outputs
Before
Hello!
5
After
However, if I put two statements, I get something wierd:
withThis(5){
println("Hello!")
println(_)
}
// Outputs
Hello!
Before
5
After
How come the "Hello!" gets printed before "Before" and then "5" is printed inside? Am I crazy?
Your last code example should be rewritten as follows to produce the expected result:
withThis(5) { x =>
println("Hello!")
println(x)
}
Otherwise, your example is equivalent to
withThis(5) {
println("Hello!")
(x: Int) => println(x)
}
as the placeholder _ will be expanded to bind as tightly as possible in a non-degenerated way (i.e., it wouldn't expand to println(x => x)).
The other thing to note is that a block always returns its last value. In your example, the last value is actually (x: Int) => println(x).
In your second example the part in curlies: { println("Hello!"); println(_) } is a block which prints "Hello!" and returns a curried println. Imagine it simplified as { println("Hello!"); 5 }, a block which prints "Hello!" and returns 5.