In Swift, one can do something like:
guard let x = z else {return} // z is "String?"
In this simple case, if z (an optional) is empty, the function will exit.
I really like this structure and recently started developing in Scala, and I was wondering if there's an equivalent in Scala.
What I found is this:
val x = if (z.isEmpty) return else z.get // z is "Option[String]"
It works - but I still wonder if there's a more "Scala-ish" way of doing it.
EDIT: the use case is that a configuration argument is allowed to be null in the app, but this specific function has nothing to do in that case. I'm looking for the correct way to avoid calling code that will not work.
Scala is functional so using return to break out early is almost always a bad idea (partly because return doesn't work the way it might appear).
In this case there are a couple of choices.
Using map allows the value inside an Option to be processed if it is there:
val xOpt = z.map { x =>
// process x
}
xOpt is a new Option that contains the results of the processing, or None if z was already None.
The alternative is to use a default value if z is None and then use that.
val x = z.getOrElse(defaultX)
// process x
In this case x is a bare value not an Option.
Admittedly I'm not familiar with Swift, but since you're not returning a value, this is presumably in a function being called for side-effect.
In Scala, the natural equivalent for "perform this side-effect if and only if this Option is non-empty is foreach:
z.foreach { x =>
// code that uses x
}
There is syntactic sugar around this, the above is equivalent to
for (
x <- z
) { // the absence of yield is significant here
// code that uses x
}
If z is empty, the foreach does nothing, so the "code that uses x would be everything in the function after the guard-let.
It might be that there's an implicit null being returned in the early exit case (it's hard to think of another value that would make sense) if this is a function being called for value. In that case, the natural equivalent would be map:
z.map { x =>
// code that computes a value from x
} // passes through None if z is empty
The for sugar would be
for (
x <- z
) yield {
// code that uses x
}
As above, "code that uses x" means everything after the guard-let.
If you happened to have two nullable arguments like
guard let x = z else { return }
guard let w = y else { return }
You could nest these or have multiple <-'s in your for expression:
for {
x <- z
w <- y
} yield {
// code that uses x and w
}
Alternatively (and my personal preference), you can use zip:
z.zip(y).foreach {
case (x, w) =>
// code that uses x and w
}
// or in the called-for-value case
z.zip(y).map {
case (x, w) =>
// code that uses x and w
}.headOption // zip creates an Iterable, so bring it back to Option
For comprehensions are similar:
def f(z: Option[String]) = for {
x <- z // x is String
result = x + " okay"
} yield result
This is useful when you have several short-circuiting operations, but the downside (compared to Swift) is you can't use other control structures such as if without some difficulty.
However, for in Scala can be used for more than just Option, e.g. to process lists:
def products(xs: Vector[Int], ys: Vector[Int]) = for {
x <- xs
y <- ys
} yield x * y // Result is a Vector of each x multiplied by each y
It is important to understand that Option is a monad. Being a monad means that it supports map and flatMap and also many other collection operations like foreach. Being a monad, and specifically supporting map, flatMap, and foreach also means that Option can be used as a generator in a for-comprehension.
The best way of thinking about Option is as a collection that can hold either 0 or 1 values. (In fact, Option does inherit from IterableOnce, and it implements several of the methods of Iterable, so you can not just think of Option as a collection, it simply is a collection.) A lot of the knowledge you have about collections transfers directly to Option, and Option supports the most important of the standard Scala collections operations, including the afore-mentioned monad operations.
So, what happens if you iterate over an empty collection? Well, nothing! What happens if you map over an empty collection? Well, you get back an empty collection!
So, the correct way of working of Options is actually not to try and get the value out of it, but instead to treat the Option as a collection.
So, instead of trying to get x out of the Option and then manipulating x, you can manipulate the value inside of the Option.
E.g. if you want to print it:
z.foreach(println)
// or
for (x <- z) println(x)
Iterating over an empty collection doesn't do anything, so this will either do nothing (if the Option is empty) or will print the value.
If you want to downcase it:
val x = z.map(_.toLowerCase())
// or
val x = for (x <- z) yield x.toLowerCase()
Note that in my case, x is an Option[String] (i.e. either a Some[String] or None) whereas in your case, x is a String, i.e. in my case, we are staying in the land of Options and don't leave.
Only at the very boundary of your system should you try and extract the value out of the Option, and the best way to do that is the method getOrElse, which does exactly what it sounds like: it gets the value out of the option if there is one, otherwise it returns the default value that you supplied.
Related
I am using a for comprehension on a stream and I would like to know how many iterations took to get o the final results.
In code:
var count = 0
for {
xs <- xs_generator
x <- xs
count = count + 1 //doesn't work!!
if (x prop)
yield x
}
Is there a way to achieve this?
Edit: If you don't want to return only the first item, but the entire stream of solutions, take a look at the second part.
Edit-2: Shorter version with zipWithIndex appended.
It's not entirely clear what you are attempting to do. To me it seems as if you are trying to find something in a stream of lists, and additionaly save the number of checked elements.
If this is what you want, consider doing something like this:
/** Returns `x` that satisfies predicate `prop`
* as well the the total number of tested `x`s
*/
def findTheX(): (Int, Int) = {
val xs_generator = Stream.from(1).map(a => (1 to a).toList).take(1000)
var count = 0
def prop(x: Int): Boolean = x % 317 == 0
for (xs <- xs_generator; x <- xs) {
count += 1
if (prop(x)) {
return (x, count)
}
}
throw new Exception("No solution exists")
}
println(findTheX())
// prints:
// (317,50403)
Several important points:
Scala's for-comprehension have nothing to do with Python's "yield". Just in case you thought they did: re-read the documentation on for-comprehensions.
There is no built-in syntax for breaking out of for-comprehensions. It's better to wrap it into a function, and then call return. There is also breakable though, but it works with Exceptions.
The function returns the found item and the total count of checked items, therefore the return type is (Int, Int).
The error in the end after the for-comprehension is to ensure that the return type is Nothing <: (Int, Int) instead of Unit, which is not a subtype of (Int, Int).
Think twice when you want to use Stream for such purposes in this way: after generating the first few elements, the Stream holds them in memory. This might lead to "GC-overhead limit exceeded"-errors if the Stream isn't used properly.
Just to emphasize it again: the yield in Scala for-comprehensions is unrelated to Python's yield. Scala has no built-in support for coroutines and generators. You don't need them as often as you might think, but it requires some readjustment.
EDIT
I've re-read your question again. In case that you want an entire stream of solutions together with a counter of how many different xs have been checked, you might use something like that instead:
val xs_generator = Stream.from(1).map(a => (1 to a).toList)
var count = 0
def prop(x: Int): Boolean = x % 317 == 0
val xsWithCounter = for {
xs <- xs_generator;
x <- xs
_ = { count = count + 1 }
if (prop(x))
} yield (x, count)
println(xsWithCounter.take(10).toList)
// prints:
// List(
// (317,50403), (317,50721), (317,51040), (317,51360), (317,51681),
// (317,52003), (317,52326), (317,52650), (317,52975), (317,53301)
// )
Note the _ = { ... } part. There is a limited number of things that can occur in a for-comprehension:
generators (the x <- things)
filters/guards (if-s)
value definitions
Here, we sort-of abuse the value-definition syntax to update the counter. We use the block { counter += 1 } as the right hand side of the assignment. It returns Unit. Since we don't need the result of the block, we use _ as the left hand side of the assignment. In this way, this block is executed once for every x.
EDIT-2
If mutating the counter is not your main goal, you can of course use the zipWithIndex directly:
val xsWithCounter =
xs_generator.flatten.zipWithIndex.filter{x => prop(x._1)}
It gives almost the same result as the previous version, but the indices are shifted by -1 (it's the indices, not the number of tried x-s).
In Scala, I have an Array[Option[(String,String,Try[String])]] and would like to find all the Failure error codes.
If the inner monad is an Option[String] instead, I can access the Some(x) contents with a clean little for comprehension, like so:
for {
Some(row) <- row
(a,b,c) = row
x <- c
} yield x
But if the inner monad is a Failure, then I'm struggling to see how to pattern match it, since I can't put Failure(x) <- c in the for statement. This feels like a really simple thing I'm missing, but any guidance would be very valuable.
Many thanks!
EDIT - Mis-specified the array. It's actually an array of option-tuple3s, not just tuple3s.
Will a.map(_._3).filter(_.isFailure) do?
EDIT: after having seen the edit and your comment, I think you can also do
val tries = for {
x <- a
z <- x
} yield z._3
tries.filter(_.isFailure)
In order to combine different types of "monads" you will need what's called a monad transformer. To put it simply, Scala doesn't let you mixin different monad types within the same for comprehension - this makes sense since a for comprehension just syntactic sugar for combinations of map / flatMap / filter.
Assuming the first one is always an Option then you could transform the Try into an Option and get the desired result:
for {
Some((a, b, c)) <- row
x <- c.toOption
} yield x
If you don't really care about what's inside that Try that's fine, but if you do then be careful that you'll lose that information when doing Some(x). If the pattern match fails, then you will get a None.
I hope that helps you.
This returns an Array[Throwable].
for {
(_,_,Failure(e)) <- rows
} yield e
Or, perhaps, an un-sugared version.
rows.collect{case (_,_,Failure(e)) => e}
Apart from:
case class A
... case which is quite useful?
Why do we need to use case in match? Wouldn't:
x match {
y if y > 0 => y * 2
_ => -1
}
... be much prettier and concise?
Or why do we need to use case when a function takes a tuple? Say, we have:
val z = List((1, -1), (2, -2), (3, -3)).zipWithIndex
Now, isn't:
z map { case ((a, b), i) => a + b + i }
... way uglier than just:
z map (((a, b), i) => a + b + i)
...?
First, as we know, it is possible to put several statements for the same case scenario without needing some separation notation, just a line jump, like :
x match {
case y if y > 0 => y * 2
println("test")
println("test2") // these 3 statements belong to the same "case"
}
If case was not needed, compiler would have to find a way to know when a line is concerned by the next case scenario.
For example:
x match {
y if y > 0 => y * 2
_ => -1
}
How compiler would know whether _ => -1 belongs to the first case scenario or represents the next case?
Moreover, how compiler would know that the => sign doesn't represent a literal function but the actual code for the current case?
Compiler would certainly need a kind of code like this allowing cases isolation:
(using curly braces, or anything else)
x match {
{y if y > 0 => y * 2}
{_ => -1} // confusing with literal function notation
}
And surely, solution (provided currently by scala) using case keyword is a lot more readable and understandable than putting some way of separation like curly braces in my example.
Adding to #Mik378's answer:
When you write this: (a, b) => something, you are defining an anonymous Function2 - a function that takes two parameters.
When you write this: case (a, b) => something, you are defining an anonymous PartialFunction that takes one parameter and matches it against a pair.
So you need the case keyword to differentiate between these two.
The second issue, anonymous functions that avoid the case, is a matter of debate:
https://groups.google.com/d/msg/scala-debate/Q0CTZNOekWk/z1eg3dTkCXoJ
Also: http://www.scala-lang.org/old/node/1260
For the first issue, the choice is whether you allow a block or an expression on the RHS of the arrow.
In practice, I find that shorter case bodies are usually preferable, so I can certainly imagine your alternative syntax resulting in crisper code.
Consider one-line methods. You write:
def f(x: Int) = 2 * x
then you need to add a statement. I don't know if the IDE is able to auto-add parens.
def f(x: Int) = { val res = 2*x ; res }
That seems no worse than requiring the same syntax for case bodies.
To review, a case clause is case Pattern Guard => body.
Currently, body is a block, or a sequence of statements and a result expression.
If body were an expression, you'd need braces for multiple statements, like a function.
I don't think => results in ambiguities since function literals don't qualify as patterns, unlike literals like 1 or "foo".
One snag might be: { case foo => ??? } is a "pattern matching anonymous function" (SLS 8.5). Obviously, if the case is optional or eliminated, then { foo => ??? } is ambiguous. You'd have to distinguish case clauses for anon funs (where case is required) and case clauses in a match.
One counter-argument for the current syntax is that, in an intuition deriving from C, you always secretly hope that your match will compile to a switch table. In that metaphor, the cases are labels to jump to, and a label is just the address of a sequence of statements.
The alternative syntax might encourage a more inlined approach:
x match {
C => c(x)
D => d(x)
_ => ???
}
#inline def c(x: X) = ???
//etc
In this form, it looks more like a dispatch table, and the match body recalls the Map syntax, Map(a -> 1, b -> 2), that is, a tidy simplification of the association.
One of the key aspects of code readability is the words that grab your attention. For example,
return grabs your attention when you see it because you know that it is such a decisive action (breaking out of the function and possible sending a value back to the caller).
Another example is break--not that I like break, but it gets your attention.
I would agree with #Mik378 that case in Scala is more readable than the alternatives. Besides the compiler confusion he mentions, it gets your attention.
I am all for concise code, but there is a line between concise and illegible. I will gladly make the trade of 4n characters (where n is the number of cases) for the substantial readability that I get in return.
I have this function:
type CustomSet = Int => Boolean
If I want to make the intersection I do something like:
def intersection(s: CustomSet, t: CustomSet): CustomSet = {
(x: Int) => contains(s, x) && contains(t, x)
}
Now, I don't see any way to check if intersection of two sets is empty...
I tried a lot of ways:
- if (intersection(s, t) == CustomSet())
- if (intersection(s, t) == None)
etc but it's not working...
Can you please tell me where I am wrong in this checking?
Just putting all the comments together:
The result of intersection is just a function. You can compare two functions for referential equality, i.e. if they are one and the same function.
There is no way to test if two functions return the same result (and have the same side effects) for all possible parameters (and system states), so all you can do is define a range of input parameters you care about and compare the results of two functions with all the results for all the interesting input parameters.
So in your case you could do something like
(-1000 to 1000).forall(!intersection(s,t)(_))
which would test if all the numbers from -1000 to 1000 are Not in the intersection of s and t
I'm coding up my first Scala script to get a feel for the language, and I'm a bit stuck as to the best way to achieve something.
My situation is the following, I have a method which I need to call N times, this method returns an Int on each run (might be different, there's a random component to the execution), and I want to keep the best run (the smallest value returned on these runs).
Now, coming from a Java/Python background, I would simply initialize the variable with null/None, and compare in the if, something like:
best = None
for...
result = executionOfThings()
if(best is None or result < best):
best = result
And that's that (pardon for the semi-python pseudo-code).
Now, on Scala, I'm struggling a bit. I've read about the usage of Option and pattern matching to achieve the same effect, and I guess I could code up something like (this was the best I could come up with):
best match {
case None => best = Some(res)
case Some(x) if x > res => best = Some(res)
case _ =>
}
I believe this works, but I'm not sure if it's the most idiomatic way of writing it. It's clear enough, but a bit verbose for such a simple "use-case".
Anyone that could shine a functional light on me?
Thanks.
For this particular problem, not in general, I would suggest initializing with Int.MaxValue as long as you're guaranteed that N >= 1. Then you just
if (result < best) best = result
You could also, with best as an option,
best = best.filter(_ >= result).orElse( Some(result) )
if the optionality is important (e.g. it is possible that N == 0, and you don't take a distinct path through the code in that case). This is a more general way to deal with optional values that may get replaced: use filter to keep the non-replaced cases, and orElse to fill in the replacement if needed.
Just use the min function:
(for (... executionOfThings()).min
Example:
((1 to 5).map (x => 4 * x * x - (x * x * x))).min
edit: adjusted to #user-unknown's suggestion
I would suggest you to rethink you whole computation to be more functional. You mutate state which should be avoided. I could think of a recursive version of your code:
def calcBest[A](xs: List[A])(f: A => Int): Int = {
def calcBest(xs: List[A], best: Int = Int.MaxValue): Int = xs match {
// will match an empty list
case Nil => best
// x will hold the head of the list and rest the rest ;-)
case x :: rest => calcBest(rest, math.min(f(x), best))
}
calcBest(xs)
}
callable with calcBest(List(7,5,3,8,2))(_*2) // => res0: Int = 4
With this you have no mutable state at all.
Another way would be to use foldLeft on the list:
list.foldLeft(Int.MaxValue) { case (best,x) => math.min(calculation(x),best) }
foldLeft takes a B and a PartialFunction of Tuple2[B,A] => B and returns B
Both ways are equivalent. The first one is probably faster, the second is more readable. Both traverse a list call a function on each value and return the smallest. Which from your snippet is what you want, right?
I thought I would offer another idiomatic solution. You can use Iterator.continually to create an infinite-length iterator that's lazily evaluated, take(N) to limit the iterator to N elements, and use min to find the winner.
Iterator.continually { executionOfThings() }.take(N).min