I have created a function to retrieve a given value from the Pascal Triangle and I've used if statements. Now I want to refactor the function to use pattern matching.
My if based function looks like this:
def valueAt(row: Int, column: Int): Int = {
// ...
else if (row == column) 1 // last column
//
}
My second version of this function, using pattern matching has the following signature:
def valueAt2(row: Int, column: Int): Int = (row, column) match {
// ...
}
Is it possible to define a case for when the row and column have the same value?
I have tried using the same variable name in the case, like this:
case (x, x) => 1 // last column
And I have also tried to use the value of the row in the column, like this:
case (_, row) => 1 // last column
But they don't work. In the first case I have a compilation error and in the second the IDE says that I'm shadowing the variable row from the match.
It this possible?
Thanks.
For the first one, use an if guard:
(1, 2) match { case (x, y) if x == y => 1; ... }
For the second one, when you want to match a variable (instead of binding and shadowing it), you can use backticks (`):
(1, 2) match { case (_, `row`) => 1; ... }
You can use a guard, which is a part of a case expression that can check non-stable conditions, and not surprisingly resembles an if statement:
(row, column) match {
case (x, y) if x == y => 1
// other cases...
}
Note that inputs not matching this guard (i.e. for which x != y) would continue to check the other cases, so, for example, another case case (x, y) => ... can follow, and assume x != y.
Related
This code don't compile, what am I doing wrong? is it possible to do it?
How can I pattern match a list with at least 2 elements, and have the pattern have a variable for the tail (meaning y :: _)
I know it's possible desugaring the :: or with a simple if. But without desugaring and without if... it's possible?
val list:List[Int] = ...
list match {
case x :: tail#(y:: _) =>
}
Try if this code works for you:
list match {
case x :: (tail#(y :: _)) =>
}
You use another variable to hold the second element:
list match {
case x :: y :: _ =>
}
This will only match a list with at least two elements, will bind x to the first element, y to the second element and ignore the rest.
If you need to just ensure the remainder of the list is at least 1 long, then
list match {
case x :: y if y.size > 0 =>
}
will do the job.
Let's say, I have the following code snippet:
val num = Future.successful(10)
num map {
case n if n > 0 => // do something
case _ // do something
}
My question is: can I simplify case n if n > 0 somehow?
I expected that I can write something like:
case _ > 0 => // do something
or with explicitly specified type (although we know that Future has inferred type [Int]):
case _: Int > 0 => // do something
Can this code be simplified somehow?
You can't simplify case n if n > 0 => ....
Every case clause in a pattern match needs to have a pattern and (optionally) a guard.
The syntax you are referring to (_ > 0) is only valid in lambdas, but there's no similar special syntax for case clauses.
If you want to simplify the guard, you can filter the Future a priori:
val num = Future.successful(10).filter(_ > 0).map { nat =>
}
Otherwise, you can keep the guard and use Future.collect:
val num = Future.successful(10).collect {
case n if n > 0 => // do something
}
One important thing to note is that if the partial function is not defined for the value which returned (i.e for your case -1) then the resulting future will be a Failure containing a NoSuchElementException.
Other than these options, you'll need the guard. I don't see any syntactically shorter way to express it.
I am trying to understand this piece of code here
def countChange(money: Int, coins: List[Int]): Int = (money, coins) match {
case (0, _) => 1
case (m, _) if m < 0 => 0
case (_, cs) if cs.isEmpty => 0
case (m, cs) => countChange(m - cs.head, cs) + countChange(m, cs.tail)
}
}
where I cannot understand the pairs (0,_), (m,_), (_,cs) and (m,cs) because the terms m and cs are undefined in the body of the code.
What is this construction in traversing the List called? A pair of some matching patterns?
The list is being traversed recursively. This construct is called pattern matching
You can read it like:
If the tuple (money, coins) is a tuple whose first value is 0 then return 1 ignore the second value of the tuple
If the tuple (money, coins) is a tuple has a first value below 0 then return 0 ignore the second value of the tuple.
And so on...
The _ is used in pattern matching to simbolize that we don't care what that parameter is, it can be anything
Pattern matching in Scala is backed by the unapply method of Objects, read more about extractors. Meaning that for each case the method unapply will be called with the tuple (money, coins) as argument and if determines that it is a match it will pass the respective first value and second value to the case clauses.
Example:
The statement case (m, _) => ... will lead to the call Tuple2.unapply((money, coins))
Note
Case classes already define unapply methods for us. That's why you can use them in pattern matching 'out of the box'. Tuple2 is a case class.
This is an example of pattern matching, which is being used to recursively traverse your list of coins. Here is the same code re-written with comments, the important thing to know is that each case statement is matching a possible pattern of the tuple, and the _ are used for ignoring pieces of the tuple.
def countChange(money: Int, coins: List[Int]): Int = {
// Construct a tuple for pattern matching on
val tuple: (Int, List[Int]) = (money, coins)
tuple match {
// Check to see if money == 0
case (0, _) => 1
// m represents money, use a guard to check if m is negative
case (m, _) if m < 0 => 0
// cs represents coins, use a guard statement check for empty list
case (_, cs) if cs.isEmpty => 0
// Recursive step. Since the patterns are tried in order, we
// now know that if we make it to here m (money) is non-zero
// and non-negative, and we know that cs (coins) is a non-empty
// list. Now we can call the recursive function safely on
// the head of the list
case (m, cs) => countChange(m - cs.head, cs) + countChange(m, cs.tail)
}
}
This construct is often used to match on more than one variable at the same time. At the top of the match, you see (money, coins). This means that it's matching on the pair of both money and coins. It doesn't have a name, because it's perfectly ordinary matching on two values simultaneously.
I cannot understand the pairs (0,_), (m,_), (_,cs) and (m,cs) because the terms m and cs are undefined in the body of the code.
These terms are defined in the code. The cases define them. That's what matching and destructuring is all about.
(money, coins) match {
case (0, _) => 1 // If money == 0, then coins is ignored and we return 1
case (m, _) if m < 0 => 0 // m = money, coins is ignored. If m < 0, return 0
case (_, cs) if cs.isEmpty => 0 // money is ignored, cs = coins.
// If we have no coins, return 0.
case (m, cs) => countChange(m - cs.head, cs) + countChange(m, cs.tail)
// Otherwise, m = money, cs = coins. Recurse down the list with
// countChange(money - coins.head, coins) + countChange(money, coins.tail)
}
The reason for the tupling (money, coins) is because these patterns depend on both money and coins. You'd either need to nest matchs (ugly) or do even more ugly boolean logic in order to replicate these semantics.
I have one c code.
I want to convert it in scala.
Here is the c code.
I am not getting the part How can I use continues updated values in scala?
Is it possible to use foldLeft in this case?
int value=9999,i,j,length=10;
A and B are some 2D Integer array and some value is changing for every element. Its not fixed for entire loop.
for(i=0;i<=5;i++){
for(j=0;j<=5;j++){
if(A[i][j]==value && B[i][j]==value)
length=length+44;
else if(A[i][j]!=value && B[i][j]==value)
if(length< 'Some value')
length=length+11
else
if(length< 'Some value')
length=length+22
}
}
How can I do this?
Equivalent code might go something like this:
def someValue(x: Int, y: Int): Int = ... // I'm treating this as some function that takes the array values and returns an Int
val A: Array[Array[Int]] = ...
val B: Array[Array[Int]] = ...
val Value = 9999 // Capitalised, so it can be used directly in case matches
( for {
i <- 0 to 5
j <- 0 to 5
} yield ((i, j)) ).foldLeft(10){ case (length, (i,j)) => (A(i)(j), B(i)(j)) match {
case (Value, Value) => length + 44
case (other, Value) if other != Value =>
if (length < someValue(A(i)(j), B(i)(j))) {
length + 11
} else {
length
}
case _ => length
}
}
I left off the second comparison of length against someValue because it isn't clear how this code could ever be reached in the C code above.
I thought I could implement n+k patterns as an active pattern in scala via unapply, but it seems to fail with unspecified value parameter: k
object NPlusK {
def apply(n : Int, k : Int) = {
n + k
}
def unapply(n : Int, k : Int) = {
if (n > 0 && n > k) Some(n - k) else None
}
}
object Main {
def main(args: Array[String]): Unit = {
}
def fac(n: Int) : BigInt = {
n match {
case 0 => 1
case NPlusK(n, 1) => n * fac(n - 1)
}
}
}
Is it possible to implement n+k patterns in Scala and in that event how?
You should look at this question for a longer discussion, but here's a short adaptation for your specific case.
An unapply method can only take one argument, and must decide from that argument how to split it into two parts. Since there are multiple ways to divide some integer x into n and k such that x = n + k, you can't use an unapply for this.
You can get around it by creating a separate extractors for each k. Thus, instead of NplusK you'd have Nplus1, Nplus2, etc since there is exactly one way to get n from x such that x = n + 1.
case class NplusK(k: Int) {
def unapply(n: Int) = if (n > 0 && n > k) Some(n - k) else None
}
val Nplus1 = NplusK(1)
val Nplus1(n) = 5 // n = 4
So your match becomes:
n match {
case 0 => 1
case Nplus1(n) => n * fac(n - 1)
}
Deconstructor unapply does not work this way at all. It takes only one argument, the matched value, and returns an option on a tuple, with as many elements as there are arguments to the your pattern (NPlusK). That is, when you have
(n: Int) match {
...
case NPlusK(n, 1)
It will look for an unapply method with an Int (or supertype) argument. If there is such a method, and if the return type is a Tuple2 (as NPlusK appears with two arguments in the pattern), then it will try to match. Whatever subpattern there are inside NPlusK (here the variable n, and the constant 1), will not be passed to unapply in anyway (what do you expect if you write case NPlusK(NPlusK(1, x), NPlusK(1, y))?). Instead, if unapply returns some tuple, then each element of the tuple will be matched to the corresponding subpattern, here n which always matches, and 1 which will match if the value is equal to 1.
You could write
def unapply(n: Int) = if (n > 0) Some((n-1, 1)) else None.
That would match when your NPlusK(n, 1). But that would not match NPlusK(n, 2), nor NPlusK(1, n) (except if n is 2). This does not make much sense. A pattern should probably have only one possible match. NPlusK(x, y) can match n in many different ways.
What would work would be something Peano integers like, with Succ(n) matching n+1.