Scala unapply magic

I personally love the unapply method. Not many people talk about it but I think it has really cool features.

A somewhat long exercise today but it will give you a great tool to use in the future !

Let’s recap quickly what unapply was used for as far as we know for the moment.

In the previous episodes, we saw unapply in the context of case class to be able to extract the fields.

The syntax is:

object HANDLER {
    def unapply(input: INPUT_TYPE): Option[OUTPUT_TYPE] = {
         // when return value is "some", it is outputed
         // when return value is "none", this match is pass
    }
}

And how it is used:

input match {
     case HANDLER(OUTPUT_TYPE) => ....
}

As you can see, the input of unapply is what enter the pattern matching structure and the output is an Option of what is being returned from the match.

Several interesting things that you can do with unapply:

  • Customize the input
  • Customize the output
  • Customize the name
  • And the most interesting part to me, you can yield the match to the next matching condition.

The last bullet to me is the most important one. It is a great tool to contain responsibilities. The Option output allows you to return something when you know what to do with it or return None when you don’t know and the higher abstraction level will make decisions on how to handle the situation. It is really powerful to me because that allows you to “fail” without failing. And try several things before giving up. Let me go into details.

    val output: OUTPUT_TYPE = input match {
        case Attempt1(result) => result
        case Attempt2(result) => result
        case Attempt3(result) => result
        case n => // when all else has failed
    }

This pattern that I use often in parser for examples, allows you to add new handler very easily. Also, each parser should be very simple, returning None when nothing can be done without having to care for the rest.

One thing to be very aware/careful about is the order, because in this structure, the first match that works will be the results. If one of your matcher is more specific than an other one, lift it up first in the order of test or a larger condition might yield true before it.

If you want to talk more about one of my favorite Scala method: unapply, jump on the Discord channel!

Reveal more information and clues
Load Exercise