Match abuse?

Do you find the following code abuse code a coincidence, and if so, what is a more elegant way to do this without a large if-else-if block?

def sum(base: Int, xs: List[Int]): Int = { base match { case 0 => 1 case _ if (base < 0) => 0 case _ if (xs.isEmpty) => 0 case _ => xs.sum } } 
+6
source share
2 answers

Yes, this is an abuse of the match. You basically just wrote a big if-else-if block, but in a more awkward form. What is wrong with if statements?

I think it's much cleaner to just write this:

 def countChange(money: Int, coins: List[Int]): Int = { if(money == 0) 1 else if (money < 0) 0 else if (coins.isEmpty) 0 else countChange(money, coins.tail) + countChange(money - coins.head, coins) } 

If you want to stick with match , you can move most of the check into a match, so that it really does something:

 def countChange(money: Int, coins: List[Int]): Int = { (money, coins) match { case (0, _) => 1 case _ if (money < 0) => 0 case (_, Nil) => 0 case (_, coinsHead :: coinsTail) => countChange(money, coinsTail) + countChange(money - coinsHead, coins) } } 
+18
source

Not. Why abuse it? This is a pretty readable IMO ...

The problem I see is that money match ... is pretty arbitrary (you only use the direct template in the first case); complete "abuse" will begin as

 () match { case _ if (money == 0) => 1 ... 

So maybe stick with if-else; you can combine the second and third condition ( if( money < 0 || coins.isEmpty ) ... )


Also note that although you โ€œknowโ€ at the end that the coins are not empty and thus can โ€œsafelyโ€ call head and tail on it, this is a typical source of unexpected runtime errors. Advantage coins match { case Nil => ...; case head :: tail => ...} coins match { case Nil => ...; case head :: tail => ...} is that you cannot make such a mistake.

+2
source

Source: https://habr.com/ru/post/926064/


All Articles