scala

Scala Pattern Matching on Passed Function


How does one pattern match Success or Failure on this method:

trait FunctionApi:
     def computeTry(funct: Try[String] => Unit): Unit = ??? // some ops

def actUponTry(functionApi: FunctionApi): String = {

     // This below could be something other than match as 
     // long as `Success` or `Failure` is apparent)

     functionApi.computeTry(...) match
     // When Try is ... (get Try + exception or value)
     // Success(value) => // Act on Success & value
                  s"Success with $value" 
     // Failure(ex) =>    // Act on Failure & ex 
                  s"Failure with exception ${ex.getString}"

}

What if FunctionApi has another method called computeTry2 is computeTry2(funct: Try[Long] => Unit): Unit, can this "match test" be more generic?

Do not use external libraries.

Maybe How to pattern match a function in Scala? is helpful?

Maybe there is a way to use another wrapper trait or method to get extract the Success / Failure params?

ADDITIONAL EDIT:

The ultimate goal is to assign a Promise to enact a Future. (I want to do this part on my own.) The calling code could look like this:

val success = Success("Some String")
val succeeding = new FunctionApi:
    def computeTry(continuation: Try[String] => Unit): Unit =
        continuation(success)
val wasSuccess = actUponTry(succeeding).computeTry()
    

EDIT #2: I managed to get this to work - I'll close this issue as the issue as this evolved.

  def actUponTry(functionApi: FunctionBasedApi): StringBasedApi = {
    class StringBasedApiX extends StringBasedApi {
      def computeTry(): String = {
        functionApi.computeTry {
          case Success(value) => s"Success with $value"
          case Failure(ex) => s"Failure with exception ${ex.getMessage}"
        }
      }
    }
    new StringBasedApiX
  }

/**
  * Dummy example of a callback-based API
  */

trait FunctionBasedApi:
  def computeTry(funct: Try[String] => String): String

  /**
   * API similar to [[CallbackBasedApi]], but based on `String` instead
   */
trait StringBasedApi:
  def computeTry(): String

with test code:

  test("test matching") {
    val success = Success("Some String")
    val stringBasedApi = new FunctionBasedApi:
      def computeTry(funct: Try[String] => String): String = funct(success)
    val wasSuccess = actUponTry(stringBasedApi).computeTry()
    assertEquals(wasSuccess,  s"Success with ${success.get}")
  }

But I found that the way I was trying to do this with futures works differently than the above code (the above ... I could not get to pattern match).


Solution

  • Maybe you're looking for

    def actUponTry(functionApi: FunctionApi): Unit = {
      functionApi.computeTry {
        case Success(str) => ???
        case Failure(e)   => ???
      }
    }
    

    https://scastie.scala-lang.org/DmytroMitin/Axi9gMbXRImB9qlonWDEWA/1