When you’re learning Scala, one of the first concepts that clicks is pattern matching. Once you get the “hammer” of pattern matching in your Scala toolbox, everything is a nail; you want to use it everywhere for everything. Pattern matching is very powerful and easy to use, but it turns out for many, many simple cases using a higher-order function is more concise and performant. I have Tony Morris’s Option Cheet Sheet bookmarked and use it almost every day.
In Lift, though, we generally use Box instead of Option. Box adds a third Failure state and a host of additional methods. I got tired of translating the Option methods to Box ones in my head so I wrote up this translation of Box methods to match statements. I used the Lift API Docs and the Lift source code to compile it.
The next hammer-that-turns-everything-into-a-nail that I encountered in learning Scala was for-comprehensions. I’m still kind of in love with them! In the interest of length, I haven’t included any examples here, but Box plays very nicely with for-comprehensions as well. I hope to cover some ways we use Box in for-comprehensions in a future post.
flatMap
foo returns a Box of any type
1 2 3 4 5 | |
map
foo returns any type
1 2 3 4 5 | |
dmap
Equivalent to .map(foo(_)).openOr(bar)
foo returns a value of the same type as bar
1 2 3 4 5 | |
choice
Equivalent to .flatMap(foo(_)).or(bar())
foo and bar are functions that return Boxes of the same type
1 2 3 4 5 | |
===
bar is a value of any type
1 2 3 4 5 | |
equals
Determines equality based upon the the Box’s content. In the case of two Failures being compared, the causes must match exactly.
bar is a value of any type
1 2 3 4 5 6 7 | |
isEmpty
This one can be tricky!
1 2 3 4 5 | |
isDefined
1 2 3 4 5 | |
exists
foo returns Boolean
1 2 3 4 5 | |
forall
foo returns Boolean
1 2 3 4 5 | |
foreach
foo returns Unit
1 2 3 4 5 | |
pass
foo takes a Box and returns Unit
1 2 3 4 5 | |
filter
foo returns Boolean
1 2 3 4 5 | |
filterMsg
Returns a Failure with the provided message if the predicate is not met.
foo returns Boolean
1 2 3 4 5 | |
filterNot
foo returns Boolean
1 2 3 4 5 | |
openOr
bar is a value of the same type or a descendant of the Box’s type
1 2 3 4 5 | |
or
bar is a Box of the same type or a descendant of the Box’s type
1 2 3 4 5 | |
toOption
Box defines an implicit conversion from Box[T] to Option[T], so you can call Option methods on Boxes if you want. This is how that implicit conversion is defined (you also can call .toOption directly.)
1 2 3 4 5 | |
toList
Box also defines an implicit conversion to Iterable, so you can call any methods from Iterable that you find useful. Note, though, that if the Box is full .toList will always return a List with one element. If you want to call Iterable methods on the value of a Box[List[Foo]] you probably want to use .elements.
1 2 3 4 5 | |
elements
.elements returns an Iterator over the value of the box. Good for manipulating the contents of a Box[List[Foo]].
1 2 3 4 5 | |
isA
Bar is a Class or primitive
1 2 3 4 5 | |
asA
Bar is a Class or primitive
1 2 3 4 5 | |
?~
Useful in for-comprehensions.
emptyMsg is a string
1 2 3 4 5 | |
?~!
Like ?~, but if the Box is already a Failure it replaces the message and chains the existing Failure.
emptyMsg is a string
1 2 3 4 5 | |
Constructors
from Option
1 2 3 4 | |
from List
This returns a Box with the head of the list, if the list isn’t empty.
1 2 3 4 | |
null-safe
This converts null values to Empty, which is very useful when you’re dealing with values from Java code.
1 2 3 4 | |
EmptyBox
While Box’s advantage over Option is that it distinguishes between the empty case and the failure case, if you don’t care whether a Box is a Failure or an Empty, you can match on EmptyBox.
The following code:
1 2 3 4 5 | |
is equivalent to:
1 2 3 4 | |
tryo
An insanely useful helper method that catches exceptions and converts them to Failures. You can also pass a list of Exception classes that should be converted to Emptys instead, and/or a callback function that should be triggered if an exception is thrown.
foo is a function that can throw an exception
1 2 3 4 5 | |