This is a barebones implementation of Scala's own Option[T]
library type, conveniently named Maybe[T]
. The name comes from the maybe monad, which also happens to be the the name of the type that is analogous to Option[T]
in Haskell.
Optional types provide an ergonomic way to enforce null-safety in many languages. The burden of remembering to check whether some value is null or not before performing some computation on it is lifted from the programmer to the compiler (which then bugs the programmer to explicitly handle it). Without an optional type, we could have the following disaster
public int sneakyFactorial(int n) {
if (n > 10) {
return null;
}
if (n == 0) {
return 1;
}
return n * sneakyFactorial(n - 1);
}
int someBigNum = sneakyFactorial(11);
// using someBigNum might lead to a NullPointerException if you
// don't check for null, the compiler also might not warn you.
We can rewrite the method above as a function that uses the Maybe[T]
type in Scala
def sneakyFactorial(n: Int): Maybe[Int] = n match {
case num if num > 10 => Nothing()
case num if num == 1 => Just(1)
case num => sneakyFactorial(num - 1).map(_ * num)
}
val maybeSomeBigNum = sneakyFactorial(11)
// using maybeSomeBigNum without destructuring it into a Just[T] or a Nothing[T] will
// cause a compiler error
maybeSomeBigNum * 2 // compiler error
// Use explicit pattern matching
maybeSomeBigNum match {
case Just(n) => n * 2 // this is fine
case Nothing() => // handle the "null" case here
}
Note that we have access to all the standard functions that are able to be called on sequences. This is because
one can effectively think of a Maybe[T]
as a unary list
// fine
maybeSomeBigNum.map(_ * 2).getOrElse(-1)
// also fine
maybeSomeBigNum.fold(-1)(_ * 2)
This is a rather contrived use case, but it demonstrates the safety gained from replacing nullable values with a
Maybe[T]
type. It can effectively eliminate a class of runtime errors caused by null pointers by forcing a check
at compile-time to make sure they are handled.
- Scala 2.12+
- sbt (Scala Build Tool)
- IntelliJ IDEA + Scala Plugin
- this is optional if you have
sbt
installed
- this is optional if you have
maybe is an sbt
project so it's relatively easy to spin up
- Run
sbt
to start the build servercompile
to build the projecttest
to run all tests under thetest
directory (spec files)clean
to remove all generated code