Search code examples
javafunctional-programmingjava-8option-typevavr

How to implement this nested flow with optionals?


I've have a method that takes String as an input and should also return a String.

The following ASCII art presents the logical flow:

Option<A> optA = finder.findA(input);

          optA
           /\
isEmpty() /  \ isDefined()  
         /    \
 "ERR_1"       Option<B> optB = finder.findB(optA.get().bid);
                      / \
           isEmpty() /   \ isDefined()
                    /     \
                "ERR_2"    opt2.get().id

Basically for given input I'm looking for A object which is returned wrapped in an Option. Then is A is present I'm looking for B - wrapped in an Option too, otherwise return ERR_1. Then if B is present return it's id, otherwise return ERR_2.

I'm wondering how it could be implemented using optionals (or pattern matching maybe?) in a nice and concise way (without any ifology) - possibly in one-liner.

Could anyone please suggest something?

Source code to try out can be found here.


Solution

  • It looks like you have 3 possible exit points:

    1. optA empty -> "ERR_1"
    2. optA not empty && optB empty -> "ERR_2"
    3. both not empty -> optB.get().bid

    You can achieve this by doing this with Javaslang:

     optA
       .map(a -> finder.findB(a.bid)
          .map(b -> b.bid)
          .getOrElse("ERR_2"))
       .getOrElse("ERR_1");
    

    If optA is empty, we will jump straight to orElse("ERR_1")

    If optA is not empty, we are using the value stored inside for getting value b.bid or "ERR_2" in case of optB emptiness.

    Also, in pure Java 8, it would look like this:

    optA
      .map(a -> finder.findB(a.bid)
        .map(b -> b.bid)
        .orElse("ERR_2"))
      .orElse("ERR_1");