4

I am new to scala. I was writing a pattern matching as below:

  val capitals = Map("France" -> "Paris", "Japan" -> "Tokyo")
  show(capitals.get("test"))
  def show(x: Option[String]) = x match {
    case Some(s) | None  => s
  }

I am getting error:

Error: illegal variable in pattern alternative
    case Some(s) | None  => s
              ^

I am trying to see how can I achieve or condition like I have in if statement in java

if (str == null || str.isEmpty())

Can you help rewrite the code or point out the mistake?

Question: How do I mention or condition in a case pattern matching?

4 Answers 4

7

This is how you pattern match on Options:

def show(x: Option[String]) = x match {
  case Some(s) => s
  case None => "N/A"
}

(by the way, you can also do something like this):

capitals.get("test").getOrElse("N/A")

Now, to add OR conditions to a pattern match case, you cannot use bound variables. This will work, however:

def show(x: Option[String]) = x match {
  case Some(_) | None => "a"
}

Note that the only difference is in Some(_) as opposed to your Some(s). Using Some(s) wouldn't make much sense because you can't reuse that s anyway (what if None comes, what would s be in that case?)

Sign up to request clarification or add additional context in comments.

4 Comments

this is informative. what I am trying ti achieve with is? ignoring this scenario..is or statement is possible? I have three case saying case Some[], case None, case _ . Instead writing three cases, i wanted to find if I can give it as or. Like I wanted do an operation on a or condition.How do i achieve it instead writing two cases?
thanks for the insightful answer. this is what exactly I am looking for.
Is it possible to reduce something like this: intOpt match { case Some(i) if (i < 2) => true case None => true case _ => false } into ... case None | Some(_) if (_ < 2) => true somehow?
@ristohietal I'm not sure, because "if" part doesn't make sense in case of None. But I also personally wouldn't like it even if it were possible. Your statement with three distinct cases makes perfect sense and is easier to read. Perhaps putting the None case before Some(i) if (i < 2) case makes it even easier to read and understand. Of course, this is all highly subjective.
2

I think this is what you are trying to achieve. If s has a value in the map return, s. If s has no value in the map, return a message indicating so.

val capitals = Map("France" -> "Paris", "Japan" -> "Tokyo")

def show(x: Option[String]) = x match {
  case Some(s)  => s
  case None     => "x has no value"
} 

show(capitals.get("mani"))

A similar and more concise version of show is capitals.get("mani").getOrElse("No value found") which returns No value found.

Further, you can use a guards to check various conditions on s such as if the first char is upper case. This first case will only match if s begins with an upper case character.

 def show(x: Option[String]) = x match {
     case Some(s) if(s.head.isUpper) => s
     case None     => "No value"
 } 

Comments

1

Matching Some(s) | None doesn't make sense, as if (true || false) (just no-op as it doesn't dispatch cases).

x match {
  case Some(s) => println(s"Some($s)")
  case _ => println("_None")
}

Comments

0

The most direct solution is using the method defined for maps, which takes the default as the second argument:

capitals.getOrElse("test","N/A")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.