What is encouraged style in comparing two numbers in Scala? - scala

When compare two numbers, we can use if-else or pattern matching:
If-else
if (guess < secretNum) println("Too small!\n")
else if (guess > secretNum) println("Too big!\n")
else {
println("You win!\n")
continueLooping = false
}
Pattern matching
guess match {
case x if x < secretNum => println("Too small!\n")
case x if x > secretNum => println("Too big!\n")
case _ => {
println("You win!\n")
continueLooping = false
}
}
Are there any clearer way to write this? and which is encouraged?
Edit
Here is the Rust way:
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => { println!("You win!"); break;
}

If you have access to the Scalaz library you can match Rust for style and clarity:
import scalaz._
import Scalaz._
guess ?|? secretNum
match {
case Ordering.LT => println("Too small!")
case Ordering.GT => println("Too big!")
case Ordering.EQ => println("You win!")
}
In terms of preference, it depends. If performance is critical then the if-else beats the pattern matching idiom. If readability is paramount, then pattern matching with the facilities Scalaz provides leads to more readable code in my opinion; It avoids the use of equational guards as you did in your example.

The if-else way. The pattern matching seems weird since you're not actually trying to match any patterns, so you end up just having more syntactic noise.

Consider method signum available in Double, Float, Long and Int classes, which maps the sign of the numerical value onto -1 (for negative), 0 (for zero) or 1 (for positive),
(gess - secretNum).signum match {
case -1 => "Too small"
case 1 => "Too big"
case _ => "You win"
}

Related

Scala ParArray pattern matching

Consider
val b = ParArray("a","b","c")
However, on pattern matching b for instance as follows,
b match {
case ParArray(_,"b",_) => 2
case _ => -1
}
<console>:11: error: object ParArray is not a case class,
nor does it have an unapply/unapplySeq member
case ParArray(_,"b",_) => 2
Thus how to pattern match ParArray ?
Thanks in Advance.
ParArray is a parallel structure. Its main usecase is to operate on the elements concurrently (see docs). That's done (roughly speaking) by concurrently applying operations on arbitratry segments of the ParArray.
For the sake of a counter example, imagine that you could unapply on ParArray. How would the match look like:
Given val b = ParArray("a","b","c","d")
b match {
case ParArray(_,"b",_) => 2
case _ => -1
}
Could be arbitrarily converted into:
//Parallel split & join:
"a","b" match {
case ParArray(_,"b",_) => 2
case _ => -1
}
"c","d" match {
case ParArray(_,"b",_) => 2
case _ => -1
}
Which of course, doesn't make sense.
For the specific case on your question, you could use direct addressing:
if (b.size == 3 && b(1)=="b") 2 else -1
In a more generic sense, a good way of reasoning is thinking of how your operation could be applied to all elements at the same time.
If you need to match on structure, you could obtain an array with the parArray.toArray method. You should also question why is a ParArray being used.

Idiomatic "do until" collection updating

Scenario:
val col: IndexedSeq[Array[Char]] = for (i <- 1 to n) yield {
val x = for (j <- 1 to m) yield 'x'
x.toArray
}
This is a fairly simple char matrix. toArray used to allow updating.
var west = last.x - 1
while (west >= 0 && arr(last.y)(west) == '.') {
arr(last.y)(west) = ch;
west -= 1;
}
This is updating all . to ch until a non-dot char is found.
Generically, update until stop condition is met, unknown number of steps.
What is the idiomatic equivalent of it?
Conclusion
It's doable, but the trade-off isn't worth it, a lot of performance is lost to expressive syntax when the collection allows updating.
Your wish for a "cleaner, more idiomatic" solution is of course a little fuzzy, because it leaves a lot of room for subjectivity. In general, I'd consider a tail-recursive updating routine more idiomatic, but it might not be "cleaner" if you're more familiar with a non-functional programming style. I came up with this:
#tailrec
def update(arr:List[Char], replace:Char, replacement:Char, result:List[Char] = Nil):List[Char] = arr match {
case `replace` :: tail =>
update(tail, replace, replacement, replacement :: result)
case _ => result.reverse ::: arr
}
This takes one of the inner sequences (assuming a List for easier pattern matching, since Arrays are trivially convertible to lists), and replaces the replace char with the replacement recursively.
You can then use map to update the outer sequence, like so:
col.map { x => update(x, '.', ch) }
Another more reusable alternative is writing your own mapUntil, or using one which is implemented in a supplemental library (Scalaz probably has something like it). The one I came up with looks like this:
def mapUntil[T](input:List[T])(f:(T => Option[T])) = {
#tailrec
def inner(xs:List[T], result:List[T]):List[T] = xs match {
case Nil => Nil
case head :: tail => f(head) match {
case None => (head :: result).reverse ::: tail
case Some(x) => inner(tail, x :: result)
}
}
inner(input, Nil)
}
It does the same as a regular map invocation, except that it stops as soon as the passed function returns None, e.g.
mapUntil(List(1,2,3,4)) {
case x if x >= 3 => None
case x => Some(x-1)
}
Will result in
List[Int] = List(0, 1, 3, 4)
If you want to look at Scalaz, this answer might be a good place to start.
x3ro's answer is the right answer, esp. if you care about performance or are going to be using this operation in multiple places. I would like to add simple solution using only what you find in the collections API:
col.map { a =>
val (l, r) = a.span(_ == '.')
l.map {
case '.' => ch
case x => x
} ++ r
}

Use same variable multiple times within one pattern

I'd like to be able to use a single variable multiple times within one pattern, so that it will only match if the same value is present in all places, such as
list match {
case x :: x :: xs => // recurse
}
which would match List(1,1,2) but would not match List(1,2,1). But this does not compile with error: x is already defined as value x.
In researching this question, I found out that I can also include a guard in the case clause, so I can do
list match {
case x1 :: x2 :: xs if x1==x2 => // recurse
}
which seems to work the same way (it does, right?). This is good, but it wouldn't look as clean if I wanted the same value in many places, like
list match {
case x1::x2::x3::x4::xs if x1==x2 && x2==x3 && x3==x4 => // recurse
}
Is there any more elegant way I can do this?
A few notes: Yes, I am just learning scala, if that wasn't clear, so I'm not sure this is something I'd ever really want to do, but I'm just interested in what's possible. In that regard, I'm not really looking for a completely different solution, like takeWhile or filter or something, but more so am specifically interested in pattern matching.
Scala doesn't provide quite that much flexibility with its matches (which may be a good thing, as one has to be aware of errors arising from unintentional variable re-use).
If you have a large number of identical items, you might want to consider a nested match (but note that you won't fail out of the inner match to be completed later down the outer match, so you have to handle everything locally):
list match {
case x :: rest => rest match {
case `x` :: `x` :: `x` :: xs => println("Four of the same")
case _ => println("Well, nonempty at least")
}
case _ => println("Boring, there's nothing here!")
}
Note the backticks which mean "we've already got this variable, check against it, don't set it!".
Alternatively, if you have specialized functionality that you use repeatedly, you can create a custom matcher:
object FourOf {
def unapplySeq(xs: List[Int]): Option[(Int, List[Int])] = xs match {
case x :: y :: z :: a :: rest if x==y && y==z && z==a => Some((x,rest))
case _ => None
}
}
and then use it whenever you need that complicated pattern:
list match {
case FourOf(x,rest) => println("four of the same")
case x :: more => println("Nonempty")
case _ => println("Yawn")
}
Neither of these are quite as tidy and flexible as what you were apparently hoping for, but then again, I'm not sure flipping between assigning and testing the same variable in a match statement is a good way to write clear code anyway.
For many repeats you might use stable identifiers to do a comparison (instead of catching a value):
val x = list.head
list match {
case `x`::`x`::`x`::`x`::xs => ....
}
But note that this won't work on empty list (you just cannot get head of it).
I think Rex's answer rocks. I am a fan of unapplySeq. But here's a not-so-clever-and-maybe-wasteful alternative, if your main bother is just with the sequence of =='s in each guard.
So in the TMTOWTDI spirit:
def same[A](xs: A*) = xs forall (xs.head==)
// Then in your pattern match,
list match {
// case x1::x2::x3::x4::xs if x1==x2 && x2==x3 && x3==x4 => // recurse
case x1::x2::x3::x4::xs if same(x1,x2,x3,x4) => // recurse
}
I like Om's answer as well, so here's an adaptation:
list.headOption map (x => list match {
case `x`::`x`::`x`::`x`::xs => //...;
case _ => // ...
}) getOrElse {
// do what you'd have done for an empty list...
}

Scala: short form of pattern matching that returns Boolean

I found myself writing something like this quite often:
a match {
case `b` => // do stuff
case _ => // do nothing
}
Is there a shorter way to check if some value matches a pattern? I mean, in this case I could just write if (a == b) // do stuff, but what if the pattern is more complex? Like when matching against a list or any pattern of arbitrary complexity. I'd like to be able to write something like this:
if (a matches b) // do stuff
I'm relatively new to Scala, so please pardon, if I'm missing something big :)
This is exactly why I wrote these functions, which are apparently impressively obscure since nobody has mentioned them.
scala> import PartialFunction._
import PartialFunction._
scala> cond("abc") { case "def" => true }
res0: Boolean = false
scala> condOpt("abc") { case x if x.length == 3 => x + x }
res1: Option[java.lang.String] = Some(abcabc)
scala> condOpt("abc") { case x if x.length == 4 => x + x }
res2: Option[java.lang.String] = None
The match operator in Scala is most powerful when used in functional style. This means, rather than "doing something" in the case statements, you would return a useful value. Here is an example for an imperative style:
var value:Int = 23
val command:String = ... // we get this from somewhere
command match {
case "duplicate" => value = value * 2
case "negate" => value = -value
case "increment" => value = value + 1
// etc.
case _ => // do nothing
}
println("Result: " + value)
It is very understandable that the "do nothing" above hurts a little, because it seems superflous. However, this is due to the fact that the above is written in imperative style. While constructs like these may sometimes be necessary, in many cases you can refactor your code to functional style:
val value:Int = 23
val command:String = ... // we get this from somewhere
val result:Int = command match {
case "duplicate" => value * 2
case "negate" => -value
case "increment" => value + 1
// etc.
case _ => value
}
println("Result: " + result)
In this case, you use the whole match statement as a value that you can, for example, assign to a variable. And it is also much more obvious that the match statement must return a value in any case; if the last case would be missing, the compiler could not just make something up.
It is a question of taste, but some developers consider this style to be more transparent and easier to handle in more real-world examples. I would bet that the inventors of the Scala programming language had a more functional use in mind for match, and indeed the if statement makes more sense if you only need to decide whether or not a certain action needs to be taken. (On the other hand, you can also use if in the functional way, because it also has a return value...)
This might help:
class Matches(m: Any) {
def matches[R](f: PartialFunction[Any, R]) { if (f.isDefinedAt(m)) f(m) }
}
implicit def any2matches(m: Any) = new Matches(m)
scala> 'c' matches { case x: Int => println("Int") }
scala> 2 matches { case x: Int => println("Int") }
Int
Now, some explanation on the general nature of the problem.
Where may a match happen?
There are three places where pattern matching might happen: val, case and for. The rules for them are:
// throws an exception if it fails
val pattern = value
// filters for pattern, but pattern cannot be "identifier: Type",
// though that can be replaced by "id1 # (id2: Type)" for the same effect
for (pattern <- object providing map/flatMap/filter/withFilter/foreach) ...
// throws an exception if none of the cases match
value match { case ... => ... }
There is, however, another situation where case might appear, which is function and partial function literals. For example:
val f: Any => Unit = { case i: Int => println(i) }
val pf: PartialFunction[Any, Unit] = { case i: Int => println(i) }
Both functions and partial functions will throw an exception if called with an argument that doesn't match any of the case statements. However, partial functions also provide a method called isDefinedAt which can test whether a match can be made or not, as well as a method called lift, which will turn a PartialFunction[T, R] into a Function[T, Option[R]], which means non-matching values will result in None instead of throwing an exception.
What is a match?
A match is a combination of many different tests:
// assign anything to x
case x
// only accepts values of type X
case x: X
// only accepts values matches by pattern
case x # pattern
// only accepts a value equal to the value X (upper case here makes a difference)
case X
// only accepts a value equal to the value of x
case `x`
// only accept a tuple of the same arity
case (x, y, ..., z)
// only accepts if extractor(value) returns true of Some(Seq()) (some empty sequence)
case extractor()
// only accepts if extractor(value) returns Some something
case extractor(x)
// only accepts if extractor(value) returns Some Seq or Tuple of the same arity
case extractor(x, y, ..., z)
// only accepts if extractor(value) returns Some Tuple2 or Some Seq with arity 2
case x extractor y
// accepts if any of the patterns is accepted (patterns may not contain assignable identifiers)
case x | y | ... | z
Now, extractors are the methods unapply or unapplySeq, the first returning Boolean or Option[T], and the second returning Option[Seq[T]], where None means no match is made, and Some(result) will try to match result as described above.
So there are all kinds of syntactic alternatives here, which just aren't possible without the use of one of the three constructions where pattern matches may happen. You may able to emulate some of the features, like value equality and extractors, but not all of them.
Patterns can also be used in for expressions. Your code sample
a match {
case b => // do stuff
case _ => // do nothing
}
can then be expressed as
for(b <- Some(a)) //do stuff
The trick is to wrap a to make it a valid enumerator. E.g. List(a) would also work, but I think Some(a) is closest to your intended meaning.
The best I can come up with is this:
def matches[A](a:A)(f:PartialFunction[A, Unit]) = f.isDefinedAt(a)
if (matches(a){case ... =>}) {
//do stuff
}
This won't win you any style points though.
Kim's answer can be “improved” to better match your requirement:
class AnyWrapper[A](wrapped: A) {
def matches(f: PartialFunction[A, Unit]) = f.isDefinedAt(wrapped)
}
implicit def any2wrapper[A](wrapped: A) = new AnyWrapper(wrapped)
then:
val a = "a" :: Nil
if (a matches { case "a" :: Nil => }) {
println("match")
}
I wouldn't do it, however. The => }) { sequence is really ugly here, and the whole code looks much less clear than a normal match. Plus, you get the compile-time overhead of looking up the implicit conversion, and the run-time overhead of wrapping the match in a PartialFunction (not counting the conflicts you could get with other, already defined matches methods, like the one in String).
To look a little bit better (and be less verbose), you could add this def to AnyWrapper:
def ifMatch(f: PartialFunction[A, Unit]): Unit = if (f.isDefinedAt(wrapped)) f(wrapped)
and use it like this:
a ifMatch { case "a" :: Nil => println("match") }
which saves you your case _ => line, but requires double braces if you want a block instead of a single statement... Not so nice.
Note that this construct is not really in the spirit of functional programming, as it can only be used to execute something that has side effects. We can't easily use it to return a value (therefore the Unit return value), as the function is partial — we'd need a default value, or we could return an Option instance. But here again, we would probably unwrap it with a match, so we'd gain nothing.
Frankly, you're better off getting used to seeing and using those match frequently, and moving away from this kind of imperative-style constructs (following Madoc's nice explanation).

scheme cond in scala language

Does scala have an equivalent to scheme's cond?
I guess you're looking for match (or just simply if/else if/else).
case class Paired(x: Int, y: Int)
def foo(x: Any) = x match {
case string : String => println("Got a string")
case num : Int if num < 100 => println("Number less than 100")
case Paired(x,y) => println("Got x and y: " + x + ", " + y)
case unknown => println("??: " + unknown)
}
The first two case statements show type based pattern matching. The third shows the use of an Extractor to break data down into constituent parts and to assign those parts to variables. The third shows a variable pattern match which will match anything. Not shown is the _ case:
case _ => println("what")
Which like the variable pattern match, matches anything, but does not bind the matched object to a variable.
The case class at the top is Scala shorthand for creating an extractor as well as the class itself.
Of course, neither match nor if does exactly the same thing as cond. One possibility is to do like this:
object Cond {
def apply(clauses: Iterable[(()=>Boolean, ()=>Any)]): Any = {
clauses find (_._1()) map (_._2()) getOrElse ()
}
}
This object accepts something Iterable where each item is a pair of a function returning Boolean and a function returning Any. It tries to find an item whose first function returns true, stops looking if it finds one, calls the second function on a found item and returns the result of that function (or () if none was found).
Examples:
val clauses = Seq(
({()=>false}, {()=>println("foo")}),
({()=>true}, {()=>println("bar")})
)
Cond(clauses)
def checkYear(year: Int) = {
Cond(Seq(
({()=>year % 400 == 0}, {()=>42}),
({()=>true}, {()=>{c:Char => (c.toString * 3)}})
))
}
ETA: Yes, I know it is ugly, but it works.
The most straightforward translation is to use pattern guards, although it requires some boilerplate. Pattern guards only work in a case pattern, and case only works in a match (unless we're writing a PartialFunction).
We can satisfy these conditions by matching a unit value against trivial cases:
;; Scheme
(cond
(foo bar)
(baz quux)
(t mydefault))
// Scala
() match {
case _ if foo => bar
case _ if baz => quux
case _ => mydefault
}