I think what you need is Option monad + !-notation.
You can use Dsl.scala for !-notation, and cats or scalaz for Option manad.
case class Name(first: Option[String], last: Option[String])
def fullName(optionName: Option[Name]) = Option {
val name = !optionName
!name.first + " " + !name.last
}
fullName(Some(Name(Some("John"), Some("Doe")))) // Some("John Doe")
fullName(None) // None
fullName(Some(Name(None, Some("Doe")))) // None
You can try the above example at https://scastie.scala-lang.org/Atry/m8NQ38cvR5yKANEGBttyPQ/1