scala sequence comprehensions
As part of my Scalatra-Docker-Postgres series, I am making an API endpoint that accepts a group of characters, and returns a collection of all valid Scrabble words that can be constructed from that group, along with their raw point values.
This means I need a function that takes a collection of letters and find all possible subset combinations. For example, given the word “dog”, I need the function to return d, o, g, do, dg, go, dgo
Notice that no combination is repeated, and that combinations are also in alphabetical (canonical) order. Having the subsets in canonical format is the key for using the SQL table for lookup.
With Scala’s built-in List
class we have all we need to make this happen. The key is the combinations
method that we get for free with an instance of List
. Read more here
One way to accomplish this task it go pure functional, using flatMap
and map
to create a data pipeline which produces the result we need. Here’s that implementation:
This sequence is not hard to read. But imagine adding a few more levels of processing before we arrive to the final map
which produces the output. We’d be looking at a long chain of functions which may look sexy but lack clarity.
Now let’s consider an alternative construct to create this function. This construct is known as many names in Scalaland:
- sequence comprehension
- for expression
- for comprehension
- for/yield loop
Is this easier to read?
Each <-
in the sequence above is a generator
which calls flatMap
, filter
or map
and produces a new collection. The final generator
yields each element in the final resulting collection to a code block (i.e. a map
function) where the final transformations occur.
In the end its up to personal style. I personally prefer the function chain style. But in the terse land of Scala, easily readable can be a rare treat.