1

I have an Option, say O, which can either be None or may have some value inside. If it has some value, that value may have a flag, say f. My requirement is that if O is None, then I create an object, say of type MyEntity,but if O has a value with flag as true, I return Nil else I create instance of MyEntity with different value. Java code can be almost as:

if(O.isEmpty) {
  MyEntity("x")
} else {
  if(O.f) {
     Nil
   } else {
    MyEntity("y") // with different value
   }
}

I want to do this in functional style using HoFs provided in scala.Option. What would be best possible way of doing it? I could this so far :

if(O.isEmpty){
 MyEntity("x")
} else {
 Option.unless(O.exists(_.f))(MyEntity("y"))
}
3
  • The return that would be Any since that si the upper bound between MyEntity and Nil are you sure you want that? Also, it may help if you provide the definition of the value inside the Option - In any case, I would write this using pattern matching rather than higher order functions. Commented Mar 24, 2021 at 17:17
  • Nil is a name of an empty list. The proper Scala code would be returning Option[MyEntity] and the implementation would be something like O.filterNot(_.f).map(_ => MyEntity("y")) Commented Mar 24, 2021 at 17:17
  • @OlegPyzhcov that doesn't work since the value inside MyEntity is different for the empty case and the non-empty but no-flag case. Commented Mar 24, 2021 at 17:20

3 Answers 3

1

I misread your question the first go round, so here is attempt #2

This is a great case for pattern matching:


val maybeMyEntity: Option[MyEntity] = option match {
    case Some(flagValue) if flagValue => None
//  case Some(true) => None (More concise, but does not highlight a handy feature)
    case Some(_) => Some(MyEntity("Y"))
    case None => Some(MyEntity("X"))
}

Pattern matching is very powerful.

Alternatively, mapping is another option:

mapping of an Option will only occur if its value is not empty, and flatMapping will remove the layer of Option added, from Option[Option[MyEntity]] to Option[MyEntity]

val result: Option[MyEntity] = if (option.isEmpty) {
    Some(Entity("X"))
} else {
    option.flatMap { flagValue =>
        if (flagValue) {
            None
        } else {
            Some(MyEntity("Y"))
        }
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

case Some(true) would look better, also you are not wrapping in Some the correct answers.
@LuisMiguelMejíaSuárez could you clarify what you mean by "you are not wrapping in Some the correct answers"? I'm afraid I don't follow.
But as to the case Some(true) would "look" better, that may be the case (looks "better" is very subjective, and clarity is paramount to stylistic choices imho), but I wanted to keep the structure as similar to that in the question posted. My hope was that the solution is very analogous to the attempt, and thus hopefully easier to understand.
@LuisMiguelMejíaSuárez I see what you mean with the Some, I've corrected it. Thank you!
0

As mentioned in the comments, Nil type is a List, and your expression should always return the same type (should really not be Any).

One possibility is to define a "sentinel" value for MyEntity, e.g.:

object MyEntity {
   val Nil = MyEntity("")
}

Now you can write:

   val result = O.fold(MyEntity("x")) { 
      case true => MyEntity.Nil
      case false => MyEntity("y")
   }

Comments

0
    case class AnOption(var flag: Boolean = true)
    
    case class MyEntities(name: String)
    
    val myOptionEntityCheck = (someOption: Option[AnOption]) => {
      someOption match {
        case None => Some(MyEntities("X"))
        case Some(aValue: AnOption) if aValue.flag => None
// OR   case Some(AnOption(true)) => None
        case Some(_) => Some(MyEntities("y"))
      }
    }

1 Comment

you are correct, for beginner it is bit confusing so added extra guard for easy understanding. Thanks jwvh

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.