Cassie
Cassie

Reputation: 3099

Generic nested Options pattern matching

I have this data structures with case class in an option and the field being wrapped in an option as well:

case class Name(value: Option[String]) extends AnyVal
case class Data(id: Int, name: Option[Name], isDefault: Boolean)

So I would like to handle cases when there is some for the Name, the same goes for upper Option. But when there is None for the Name I would like to have None as the result instead of Some(Name(None)). I tried to do something like this:

def handleNestedOptions(value: Option[String]): Option[Name] = {
  value match {
    case Some(data) => Some(Name(Some(data)))
    case None => None
  }
}

But I also would like to have it in a generic way so it could work for any case class of the same structure I have. So how can I change this implementation to make it more generic? By generic I mean something like this: def handleNestedOptions[T, K](value: Option[K]): Option[T]

Upvotes: 1

Views: 84

Answers (1)

jwvh
jwvh

Reputation: 51271

Here's one way about it.

def handleNestedOptions[T,U](value :Option[T], f :Option[T]=>U) :Option[U] =
  if (value.isEmpty) None
  else Option(f(value))

handleNestedOptions(None, Name)        //res0: Option[Name] = None
handleNestedOptions(Some("str"), Name) //res1: Option[Name] = Some(Name(Some(str)))

Upvotes: 3

Related Questions