In this post we’ll finally start using Scalaz. We’ll look at how to get Scalaz using
sbt and look at how it provides us with type-safe equality checking.
Add the following line to your
libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.2.14"
I highly recommend Ammonite Scala REPL. It provides a lot of improvements over the standard REPL like being able to import library dependencies straight from the console. I’ll be using Ammonite REPL henceforth because it’ll help me keep the examples in the REPL. However, there isn’t any difference beyond how to get the dependencies.
No matter what your preferred REPL is, let’s get started.
Start the REPL by executing
sbt console. Then, execute the following:
scala> import scalaz._
Start the REPL by executing the
amm command. Then, execute the following:
@ import $ivy.`org.scalaz::scalaz-core:7.2.14`
We can compare two values in Scala using
== (double equals). The issue, however, is that it will let us compare unrelated types like a string with an integer and such a comparison would always yield false.
@ 1 == "1"
== operator that Scala provides is a null-safe comparison operator and not type-safe. What if we want type-safety, too? This is where Scalaz’s
=== (triple equals) comes in. It’ll complain when you try to compare unrelated types.
@ 1 === "1"
Similarly, we can check for inequalities. The Scala operator
!= is null-safe but not type-safe.
@ 1 != "1"
Here’s the Scalaz way to check for inequality using
=/= operator which is both type-safe and null-safe:
@ 1 =/= "1"
As always, there are type classes at play here. There is an
Equal trait which provides an
equal to check if the two values are equal and of the same type.
def equal(a1: F, a2: F): Boolean
Since all this magic is done using type classes, how about we put it to use and write code to compare two
@ case class Person(id: Int, name: String)
=== lets you check for equality in a type-safe way. More often than not, this is what you need. Trying to compare values of dissimilar types is usually not needed. Using
=== ensures that such comparisons lead to errors at compile-time instead of waiting for them to surface at run-time. This makes debugging much more efficient.