When we have multiple Options and only want to do something when they're all set. In this example we have a property file with multiple configurations for one thing. A host and a port, we only want to use them if they're both set.

//The individual properties
val stubHost: Option[String] = Some("host")
val stubPort: Option[Int] = Some(8090)

//The case class I'll turn them into
case class StubConfig(host: String, port: Int)

We can chain them using map and flatMap.

def chainConfigs(stubHost: Option[String], stubPort: Option[Int]): Option[StubConfig] = {
  stubHost.flatMap { host: String =>
    stubPort.map { port: Int =>
      StubConfig(host, port)
    }
  }
}

Then the following statements are all true.

chainConfigs(Some("host"), Some(8090)) == Some(StubConfig("host", 8090))
chainConfigs(Some("host"), None) == None
chainConfigs(None, Some(8090)) == None
chainConfigs(None, None) == None

We can even use a for loop to make it more readable.

def chainConfigs(stubHost: Option[String], stubPort: Option[Int]): Option[StubConfig] = {
  for {
    host <- stubHost
    port <- stubPort
  } yield StubConfig(host, port)
}
shadow-left