0

There is a class

class MyType {
  def status(): String = "Connected" // demo implementation
}

I have a val x: Option[Option[MyType]]. I need to process this value like the following:

x match {
  case None => "Error1"
  case Some(None) => "Error2"
  case Some(Some(t)) => t.status
}

I would like to rewrite the same code with higher order functions as it described in Tom Morris post. What is the correct way to code it?


There are some words about the motivation to ask the question. Official documentation says:

The most idiomatic way to use an scala.Option instance is to treat it as a collection or monad and use map,flatMap, filter, or foreach <...> A less-idiomatic way to use scala.Option values is via pattern matching

I am not quite sure I realize what "idiomatic" means exactly, but it sounds like "good" for me.

Loom
  • 9,768
  • 22
  • 60
  • 112
  • 1
    Note that the last `match` should be `case Some(Some(t)) => t.status` – Tim May 04 '20 at 07:09
  • 1
    Just sharing my two cents, if you follow @Tim advice, I would go with **pattern matching** instead of with **higher-order functions**. IMHO, it is more readable. – Luis Miguel Mejía Suárez May 04 '20 at 13:25
  • @Tim - Thank you. I'll fix – Loom May 04 '20 at 15:19
  • @LuisMiguelMejíaSuárez - Thank you. I expanded the question with motivation to rewrite **pattern matching** code – Loom May 05 '20 at 12:14
  • 1
    @Loom while the phrase about the use of `Option` as a **Monad** being more idiomatic _(meaning more common / standard / good)_ is true. It also depends on the context. That, phrase refers more when you are composing multiple options with multiple functions. However, in your case, that you only want to get the result, I find **pattern matching** easier to read. - However, I may add that having an `Option[Option[X]]` is usually strange, maybe it would have been a more idiomatic way to get the same end result. I am thinking that maybe you should have used `Either`. – Luis Miguel Mejía Suárez May 05 '20 at 13:00
  • @LuisMiguelMejíaSuárez - Thank you! – Loom May 05 '20 at 13:11

2 Answers2

4

Something like this?

x.fold("Error1")(_.fold("Error2")(_.status()))
jwvh
  • 50,871
  • 7
  • 38
  • 64
0

map-way:

x.map(_.map(_.status).getOrElse("Error2")).getOrElse("Error1")
Loom
  • 9,768
  • 22
  • 60
  • 112