Scalaz BooleanOps

In this post we’ll look at BooleanOps and the goodies it provides to work with Booleans. As always, we’ll go straight to examples.

Unless

1
2
3
4
5
6
7
8
9
10
11
12
13
@ import scalaz._
import scalaz._
@ import Scalaz._
import Scalaz._
@ val t = true
t: Boolean = true
@ val f = false
f: Boolean = false
// executes the given side-effect if this boolean value is false
@ t unless "this won't print".println

@ f unless "this will print".println
"this will print"

As the comment for unless states:

Executes the given side-effect if this boolean value is false.

A mnemonic to remember the working is: “Unless the value is true, execute the side-effecting function”.

When

1
2
3
4
5
// executes the given side-effect if this boolean value is true
@ t when "this will print".println
"this will print"

@ f when "this won't print".println

The “opposite” of unless is when which executes the function when the value is true. As the comment for when states:

Executes the given side-effect if this boolean value is true.

A mnemonic to remember the working is: “When the value is true, execute the side-effecting function”.

Folding a Boolean

1
2
3
4
@ t fold[String]("this will be returned when true", "this will be returned when false")
res8: String = "this will be returned when true"
@ f fold[String]("this will be returned when true", "this will be returned when false")
res9: String = "this will be returned when false"

fold lets you decide what value to return depending on whether it is true or false.

Converting to an Option

1
2
3
4
@ t option "this will create a Some() with this string in it"
res10: Option[String] = Some("this will create a Some() with this string in it")
@ f option "this will result in a None"
res11: Option[String] = None

option lets us convert a Boolean into an Option in a type-safe manner. A true results in a Some containing the value passed to option whereas a false results in an Option of whatever the type of the argument is.

Ternary Operator

1
2
3
4
@ t ? "true" | "false"
res13: String = "true"
@ f ? "true" | "false"
res14: String = "false"

Scalaz also provides a ternary operator to work with Booleans. The ternary operator is actually a combination of ? and |. ? is the conditional operator that results in the creation of an object of Conditional and | is a method of that object.

Miscellaneous

1
2
3
4
@ t ?? List(1, 2, 3)
res15: List[Int] = List(1, 2, 3)
@ f ?? List(1, 2, 3)
res16: List[Int] = List()

?? returns the given argument if the value is true, otherwise, the zero element for the type of the given argument. In our case, the “zero” element for List is an empty List.

1
2
3
4
@ t !? List(1, 2, 3)
res17: List[Int] = List()
@ f !? List(1, 2, 3)
res18: List[Int] = List(1, 2, 3)

!? is the opposite of ?? and returns the argument if the value is false or the zero element otherwise.

Conclusion

This brings us to the end of our post on BooleanOps. There’s a lot more functions provided but I’ve chosen to cover those which I feel will be the most useful.

Scalaz TryOps

In this post we’ll look at TryOps and the goodies it provides to work with scala.util.Try. To recap, here’s what Try does:

The Try type represents a computation that may either result in an exception, or return a successfully computed value. It’s similar to, but semantically different from the scala.util.Either type.

Converting to a Disjunction

1
2
3
4
5
6
7
8
9
10
11
12
@ import scalaz._
import scalaz._
@ import Scalaz._
import Scalaz._
@ import scala.util.Try
import scala.util.Try
// an operation that may potentially throw an exception
@ val t1 = Try { "1".toInt }
t1: Try[Int] = Success(1)
// converting to a Scalaz disjunction
@ val disjunction = t1 toDisjunction
disjunction: Throwable \/ Int = \/-(1)

The result of a Try is either a Success or a Failure. This can very easily be translated to a Scalaz disjunction. A Success produces a right disjunction whereas a Failure produces a left disjunction.

Converting to a Validation

1
2
@ val validation = t1 toValidation
validation: Validation[Throwable, Int] = Success(1)

Similarly, if this Try were a part of validating your data like checking values in a JSON object, you can convert this to a Scalaz Validation.

Converting to a ValidationNel

1
2
@ val nel = t1 toValidationNel
nel: ValidationNel[Throwable, Int] = Success(1)

ValidationNel is useful for accumulating errors. We’ll cover all of this in coming posts.

Conclusion

This brings us to the end of the post on TryOps. In coming posts we’ll look at Validation type which lets us represent, as you might have guessed, the result of validating an input. Similarly, if we want to accumulate all the results of validating inputs, we use ValidationNel. Both of these are subjects of coming posts.

Scalaz TupleOps

In this post we’ll look at TupleOps and the goodies it provides to work with Tuples. There’s no TupleOps.scala file in the GitHub repo because the file is generated by GenerateTupleW. You can see the code for TupleOps if you’re using an IDE like IntelliJ. There’s a number of TupleNOps classes like Tuple2Ops[A, B], etc. all the way to Tuple12Ops[A, B].

With that said, let’s jump into examples. We’ll look at what Tuple2Ops provides us. Everything is analogous to Tuple3Ops, etc. It’s just the number of arguments to the methods that will change.

Folding a Tuple

1
2
3
4
5
6
@ import scalaz._
import scalaz._
@ import Scalaz._
import Scalaz._
@ (1, 2) fold( (_1, _2) => _1 + _2 )
res2: Int = 3

fold in Tuple2Ops takes a function which accepts 2 arguments i.e. equal to the arity of the tuple. Here, we’re folding the tuple and adding together its two Int elements but you can do whatever you want.

Converting to IndexedSeq

1
2
@ (1, 2) toIndexedSeq
res3: collection.immutable.IndexedSeq[Int] = Vector(1, 2)

This one is self-explanatory. The tuple is converted to an IndexedSeq.

Mapping Elements in a Tuple

1
2
@ (1, 2) mapElements(_1 => _1 * 2, _2 => _2 * 2)
res4: (Int, Int) = (2, 4)

mapElements in Tuple2Ops takes 2 functions as arguments, 1 for each element of the tuple. The functions are then applied to their corresponding elements and the result is returned as a Tuple. In the example above, we’re just multiplying both the elements by 2.

This is different from the map from the standard library. The map from the standard library only operates on the last element of the tuple.

1
2
@ (1, 2) map (_ * 2)
res5: (Int, Int) = (1, 4)

Conclusion

That’s the end of the post on TupleOps. TupleOps‘s convenience methods can be used to manipulate tuples easily.

Scalaz StringOps

In this post we’ll look at StringOps and the goodies it provides to work with Strings. Like we did last time, we’ll jump straight into examples.

Plural

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@ import scalaz._
import scalaz._
@ import Scalaz._
import Scalaz._
// keep the doctor away
@ "apple" plural 2
res2: String = "apples"
// oops!
@ "dress" plural 3
res3: String = "dresss"
// singular
@ "apple" plural 1
res4: String = "apple"
// is it Friday, yet?
@ "day" plural 3
res5: String = "days"

Scalaz provides a convenient plural method on String to get its plural form. Going over the docs for plural:

Returns the same String value if the given value is 1 otherwise pluralises this String by appending an “s” unless this String ends with “y” and not one of [“ay”, “ey”, “iy”, “oy”, “uy”] in which case the ‘y’ character is chopped and “ies” is appended.

This explains why the plural of “dress” was “dresss” with 3 “s”; plural simply appended an “s”. Nonetheless, this is a convenient method.

Non-Empty List

1
2
3
4
@ "list" charsNel
res6: Option[NonEmptyList[Char]] = Some(NonEmpty[l,i,s,t])
@ "" charsNel
res7: Option[NonEmptyList[Char]] = None

charsNel converts the String into an Option[NonEmptyList[Char]]. This method is useful if the string represents a sequence of actions to be taken as characters. For example, “OCOC” could mean “Open, Close, Open, Close” or something and charsNel would convert this into an Option of NonEmptyList[Char]. You can then iterate over the characters and take whatever action you want to.

Parsing

Scalaz provides convenient methods for parsing a String into Boolean, Int, etc. The advantage of using these over standard Scala parsing methods is that these methods return a Validation. You can then fold the Validation object to see whether the value was successfully parsed or resulted in an error. This is good for functional programming as you don’t have to catch exceptions. We’ll first look at the Scala way and then the Scalaz way.

1
2
3
4
5
6
7
8
9
10
11
// Scala way
@ "1".toInt
res8: Int = 1
@ "x".toInt
java.lang.NumberFormatException: For input string: "x"
...
// Scalaz way
@ "1".parseInt.fold(err => "failed parse".println, num => num.println)
1
@ "x".parseInt.fold(err => "failed parse".println, num => num.println)
"failed parse"

It’s also possible to parse values to BigDecimal and BigInt.

1
2
@ "3.14159265358979323846".parseBigDecimal.fold(err => "failed parse".println, num => num.println)
3.14159265358979323846

Conclusion

This covers the convenience methods Scalaz provides for dealing with Strings. The parseXXX methods are the most useful as they avoid having to deal with an exception.

Scalaz OptionOps

In this post we’ll look at OptionOps and the goodies it provides to work with Options. We’ll jump straight into examples.

Creating Options

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@ import scalaz._
import scalaz._
@ import Scalaz._
import Scalaz._
// Some
@ some(13)
res2: Option[Int] = Some(13)
// Calling some on a value
// Notice something about res variable? ;)
@ 13.some
res9: Option[Int] = Some(13)
// None
@ none
res3: Option[Nothing] = None
@ none[Int]
res4: Option[Int] = None

Extracting Values

1
2
3
4
5
6
7
8
9
10
11
12
// using unary ~ operator
@ ~ res2
res5: Int = 13
// using some / none
@ res2 some { _ * 2 } none { 0 }
res6: Int = 26
// using | operator
@ res2 | 0
res7: Int = 13
// extracting value from none
@ ~ res4
res8: Int = 0

The unary ~ extracts the value from the Option or returns the zero value for that type. For example, in case of Int it’ll return the value in the Option or return 0. The some{ .. } none { .. } construct lets you specify what value to return in case of Some and None. I am multiplying the value by 2 and thus returning 26. As you can see, Scalaz provides with more expressive and type-safe way to create and extract values from Option.

Notice that the type of all the resulting variables is Option instead of Some or None. This is more type-safe than using None because you’d get None.type, and the type inferencer would allow the type to be Option[Int] or Option[String] whereas none[Int] is guaranteed to be an Option[Int]. The type inferencer will enforce this.

Miscellaneous

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// we'll have fun with these values
@ val o = some("option")
o: Option[String] = Some("option")
@ val n = none[String]
n: Option[String] = None

// None to right disjunction
@ n toRightDisjunction "onTheLeft"
res10: String \/ String = -\/("onTheLeft")
// Folding the disjunction prints the value on the left
@ res10 fold(l => s"Left: $l".println, r => s"Right: $r".println)
"Left: onTheLeft"

// Some to right disjunction
@ o toRightDisjunction "onTheLeft"
res11: String \/ String = \/-("option")
// Folding the disjunction prints the value on the right
@ res11 fold(l => s"Left: $l".println, r => s"Right: $r".println)
"Right: option"

// default values, similar to unary ~
@ n.orZero
res12: String = ""

// ternary operator
@ o ? "some" | "none"
res13: String = "some"

Scalaz provides us with a disjunction which is a replacement for Scala Either. I’ve only introduced disjunction here and will cover it later in a post of its own. Trying to convert a None to a right disjunction doesn’t work. We get back a left disjunction as indicated by -\/. Similarly, converting a Some to right disjunction works, as indicated by \/-. Scalaz also provides a ternary operator to work with Options.

Conclusion

This sums up, non-exhaustively, how we can use the convenience methods that Scalaz provides on top of Options that lets us code in more expressive and type-safe way.

Scalaz Enum

In this post we’ll look at how to create enum using Scalaz. However, we’ll first look at how to create enum using standard Scala library.

Enum - Scala Way

An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it. Common examples include compass directions (values of NORTH, SOUTH, EAST, and WEST) and the days of the week.[1]

There are a couple of ways in which you can create enum in Scala.

Using scala.Enumeration

Defines a finite set of values specific to the enumeration. Typically these values enumerate all possible forms something can take and provide a lightweight alternative to case classes.

Let’s see an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@ object Direction extends Enumeration {
type Direction = Value
val NORTH, EAST, WEST, SOUTH = Value
}
defined object Direction
@ import Direction._
import Direction._
@ Direction withName "NORTH"
res2: Value = NORTH
@ Direction.values foreach println
NORTH
EAST
WEST
SOUTH

Advantages:

  • Lightweight.
  • Easy to use.
  • Iterable.
  • Disadvantages:

  • They only exist as unique values. You cannot add behavior to them.
  • Using Case Objects

    Enum can also be created using sealed trait. A sealed trait requires all the classes or traits extending it be in the same file in which it is defined.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @ object Direction {
    sealed trait Direction
    case object NORTH extends Direction
    case object EAST extends Direction
    case object WEST extends Direction
    case object SOUTH extends Direction
    }
    defined object Direction
    @ import Direction._
    import Direction._

    Advantages:

  • Each value is an instance of its own type and it's possible to add behavior to them.
  • Disadvantages:

  • A case object generates a lot more code than `Enumeration`.
  • Not iterable.
  • Enum - Scalaz Way

    Scalaz allows creating enum using Enum trait. Scalaz enums are more powerful than the standard Scala enums. Let’s see some examples of creating Scalaz enum[2]:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    @ import scalaz._
    import scalaz._
    @ import Scalaz._
    import Scalaz._
    // as a List
    @ 'a' |-> 'z'
    res3: List[Char] = List(
    'a',
    'b',
    'c',
    'd',
    'e',
    'f',
    ...
    // as a Scalaz stream
    @ 'a' |=> 'z'
    res4: EphemeralStream[Char] = scalaz.EphemeralStream$$anon$5@2fb4925c

    Scalaz also provides us with succ and pred to get the successor and predecessor.

    1
    2
    3
    4
    @ 'B'.succ
    res6: Char = 'C'
    @ 'B'.pred
    res7: Char = 'A'

    It’s also possible to easily step through the enumeration.

    1
    2
    3
    4
    5
    6
    // 3 steps forwards
    @ 'B' -+- 3
    res8: Char = 'E'
    // 3 steps backwards
    @ 'B' --- 3
    res9: Char = '?'

    You can also get min and max values for an enumeration.

    1
    2
    3
    4
    @ implicitly[Enum[Int]].min
    res10: Option[Int] = Some(-2147483648)
    @ implicitly[Enum[Int]].max
    res11: Option[Int] = Some(2147483647)

    Let’s create our own enumeration using Scalaz Enum.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    @ import scalaz._
    import scalaz._
    @ import Scalaz._
    import Scalaz._
    @ object Size {
    case class Size(val size: Int, val name: String)
    val SMALL = Size(0, "SMALL")
    val MEDIUM = Size(1, "MEDIUM")
    val LARGE = Size(2, "LARGE")

    implicit object SizeEnum extends Enum[Size] with Show[Size] {
    def order(s1: Size, s2: Size): Ordering = (s1.size compare s2.size) match {
    case -1 => Ordering.LT
    case 0 => Ordering.EQ
    case 1 => Ordering.GT
    }

    def succ(s: Size): Size = s match {
    case SMALL => MEDIUM
    case MEDIUM => LARGE
    case LARGE => SMALL
    }

    def pred(s: Size): Size = s match {
    case SMALL => LARGE
    case MEDIUM => SMALL
    case LARGE => MEDIUM
    }

    def zero: Size = SMALL

    override def shows(s: Size) = s.name

    override def max = Some(LARGE)

    override def min = Some(SMALL)
    }
    }
    defined object Size
    @ import Size._
    import Size._
    // step through
    @ SMALL -+- 1
    res4: Size = Size(1, "MEDIUM")
    // as a list
    @ SMALL |-> LARGE
    res5: List[Size] = List(Size(0, "SMALL"), Size(1, "MEDIUM"), Size(2, "LARGE"))
    // show
    @ SMALL.println
    SMALL
    // max
    @ implicitly[Enum[Size]].max
    res6: Option[Size] = Some(Size(2, "LARGE"))
    // min
    @ implicitly[Enum[Size]].min
    res7: Option[Size] = Some(Size(0, "SMALL"))

    Notice that since we’re using implicitly[], we don’t have to provide the exact name of the typeclass extending Enum[Size], the compiler will figure it out from the implicits within scope.

    Conclusion

    Although Scalaz Enum may seem like a long-winded way to do something trivial, they offer you a lot more flexibility and brevity over vanilla Scala enum. However, I believe that the full force of Scalaz Enum is needed only when you have ordered elements like size. For cases like compass directions, Scala enum are better-suited.

    Scalaz Show

    In this post we’ll look at Scalaz Show. The only purpose of this trait is to provide a String representation for its subtypes.

    A Simple Example

    1
    2
    3
    4
    5
    6
    7
    8
    @ import scalaz._
    import scalaz._
    @ import Scalaz._
    import Scalaz._
    @ 3.show
    res2: Cord = Cord(1 [3])
    @ 3.println
    3

    As always, there are implicits defined for Int, Float, etc. Calling println returns a String whereas calling show returns a Cord. Going over the source code for Cord:

    A Cord is a purely functional data structure for efficiently storing and manipulating Strings that are potentially very long.

    Why Use Show?

    A reasonable question to ask is why use Show when we have a toString which produces a String representation of objects. The answer is that toSring doesn’t always produce a useful representation.

    1
    2
    @ println(new Thread())
    Thread[Thread-185,5,main]

    Showing a Thread

    So, let’s create a Show for Thread.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @ implicit object ThreadShowable extends Show[Thread] {
    override def shows(t: Thread): String = s"Thread Id=${t.getId} name=${t.getName}"
    }
    defined object ThreadShowable
    @ val t = new Thread()
    t: Thread = Thread[Thread-322,5,main]
    // Scala way
    @ println(t)
    Thread[Thread-322,5,main]
    // Scalaz way
    @ t.println
    Thread Id=352 name=Thread-322

    Conclusion

    Show is probably not that interesting and probably exists because there is Show class in Haskell[1]:

    The instances of class Show are those types that can be converted to character strings (typically for I/O)

    Scalaz Order

    In this post we’ll look at how to implement ordering using Scalaz Order trait. However, before we do that, let’s step back a little and look at how we implement ordering using scala.math.Ordering

    Sorting a Collection - Scala Way

    Say we have a List and we’d like to sort it.[1] We can do so by calling the sorted method on it and it’ll work out-of-the-box for lists of Int, Float, etc. because there is an implicit in scala.math.Ordering.

    1
    2
    @ List(1, 2, 3, 5, 4, 10, -1, 0).sorted
    res0: List[Int] = List(-1, 0, 1, 2, 3, 4, 5, 10)

    Going over the documentation for scala.math.Ordering[2]:

    Ordering is a trait whose instances each represent a strategy for sorting instances of a type.
    Ordering’s companion object defines many implicit objects to deal with subtypes of AnyVal (e.g. Int, Double), String, and others.

    All the implicit objects in the companion object implement the scala.math.Ordering trait which extends the java.util.Comparator interface. Thus, they all have a compare method. What if we have types for which there is no sorting strategy in the companion object of scala.math.Ordering? We define our own like so:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @ case class Salary(amt: Float)
    defined class Salary
    @ implicit object SalaryOrdered extends Ordering[Salary] {
    // we are using compare on type Float
    def compare(a: Salary, b: Salary): Int = a.amt compare b.amt
    }
    defined object SalaryOrdered
    @ List(Salary(999.0f), Salary(555.0f)).sorted
    res4: List[Salary] = List(Salary(555.0F), Salary(999.0F))

    But we still don’t have operators like <, <=, etc. on type Salary.

    1
    2
    3
    4
    5
    @ Salary(999.0f) > Salary(555.0f)
    cmd3.sc:1: value > is not a member of ammonite.$sess.cmd0.Salary
    val res3 = Salary(999.0f) > Salary(555.0f)
    ^
    Compilation Failed

    To do that, the trait scala.math.Ordered would have to be mixed in.

    1
    2
    3
    4
    5
    6
    7
    8
    @ case class Salary(amt: Float) extends Ordered[Salary] {
    override def compare(that: Salary): Int = this.amt compare that.amt
    }
    defined class Salary
    @ Salary(1.0f) < Salary(2.0f)
    res1: Boolean = true
    @ List(Salary(2.0f), Salary(2.0f), Salary(1.0f)).sorted
    res2: List[Salary] = List(Salary(1.0F), Salary(2.0F), Salary(2.0F))

    And we know that if we’re working with a library, we do not have the liberty to mix a trait for our convenience. Also, Scala’s comparison operators are not type safe.

    1
    2
    @ 1 > 2.0
    res4: Boolean = false

    Sorting a Collection - Scalaz Way

    As stated before, Scalaz provides Order trait. Staying with our Salary example, let’s put Scalaz Order to use.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    @ import scalaz._
    import scalaz._
    @ import Scalaz._
    import Scalaz._
    @ case class Salary(amt: Float)
    defined class Salary
    @ implicit object SalaryOrder extends Order[Salary] {
    override def order(a: Salary, b: Salary): Ordering = {
    a.amt compare b.amt match {
    case -1 => Ordering.LT
    case 0 => Ordering.EQ
    case 1 => Ordering.GT
    }
    }
    }
    defined object SalaryOrder

    We’ve defined a way to order Salary objects using Scalaz Order trait via a typeclass. The implicit object needs to provide an implementation for order method which returns an Ordering value. Going over the code for Scalaz Ordering:

    This Ordering is analogous to the Ints returned by scala.math.Ordering.

    Now, we have comparison operators at our disposal. Here’s how we can compare Salary objects using the ?|? operator:

    1
    2
    @ Salary(1.0f) ?|? Salary(2.0f)
    res4: Ordering = LT

    ?|? can also be used with Int, Float, etc. and is type-safe.

    1
    2
    3
    4
    5
    6
    7
    @ 1.0 ?|? 2.0
    res5: Ordering = LT
    @ 1.0 ?!? 2
    cmd6.sc:1: value ?!? is not a member of Double
    val res6 = 1.0 ?!? 2
    ^
    Compilation Failed

    Also, analogous to <, <=, we now have type-safe lt, lte, etc.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @ 1.0 gte 2.0
    res6: Boolean = false
    @ 1 gt 2.0
    cmd8.sc:1: type mismatch;
    found : Double(2.0)
    required: Int
    val res8 = 1 gt 2.0
    ^
    Compilation Failed

    That’s not where the power ends. You can also compare Options seamlessly. Do note that it is some with a lowercase “s”.

    1
    2
    @ some(Salary(1.0f)) ?|? some(Salary(2.0f))
    res8: Ordering = LT

    You can now also use sorted on a collection equally easily. Using Order[A].toScalaOrdering we can get back an object of type scala.math.Ordering which we can use to sort collections.

    1
    2
    3
    4
    @ implicit val salaryOrdering = Order[Salary].toScalaOrdering
    salaryOrdering: math.Ordering[Salary] = scalaz.Order$$anon$1@5b8a5d7c
    @ List(Salary(2.0f), Salary(1.0f), Salary(0.0f)).sorted
    res10: List[Salary] = List(Salary(0.0F), Salary(1.0F), Salary(2.0F))

    Also, since Order trait extends the Equal trait, you get the === operator, too.

    1
    2
    @ Salary(0.0F) === Salary(1.0F)
    res11: Boolean = false

    Conclusion

    By using Scalaz Order trait, we can implement comparison between values in a type-safe and extensible way. There’s seamless transformation from Scalaz Order to scala.math.Ordering which lets us use the sorted method on collections.

    Scalaz Equal

    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.

    Getting Scalaz

    Add the following line to your build.sbt file:

    1
    libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.2.14"


    NOTE:

    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.


    Fire Up the REPL

    No matter what your preferred REPL is, let’s get started.

    Standard REPL

    Start the REPL by executing sbt console. Then, execute the following:

    1
    2
    3
    4
    5
    scala> import scalaz._
    import scalaz._

    scala> import Scalaz._
    import Scalaz._

    Ammonite

    Start the REPL by executing the amm command. Then, execute the following:

    1
    2
    3
    4
    5
    6
    @ import $ivy.`org.scalaz::scalaz-core:7.2.14`
    import $ivy.$
    @ import scalaz._
    import scalaz._
    @ import Scalaz._
    import Scalaz._

    Equality Checking

    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
    2
    @ 1 == "1"
    res3: Boolean = false

    The == 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
    2
    3
    4
    5
    6
    7
    @ 1 === "1"
    cmd4.sc:1: type mismatch;
    found : String("1")
    required: Int
    val res4 = 1 === "1"
    ^
    Compilation Failed

    Similarly, we can check for inequalities. The Scala operator != is null-safe but not type-safe.

    1
    2
    @ 1 != "1"
    res4: Boolean = true

    Here’s the Scalaz way to check for inequality using =/= operator which is both type-safe and null-safe:

    1
    2
    3
    4
    5
    6
    7
    @ 1 =/= "1"
    cmd5.sc:1: type mismatch;
    found : String("1")
    required: Int
    val res5 = 1 =/= "1"
    ^
    Compilation Failed

    Under the Hoods

    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.

    1
    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 Person objects?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @ case class Person(id: Int, name: String)
    defined class Person
    @ implicit object PersonEquals extends Equal[Person] {
    // we are using Scalaz === internally
    def equal(a1: Person, a2: Person): Boolean = a1.id === a2.id && a1.name === a2.name
    }
    defined object PersonEquals
    @ Person(1, "John") === Person(2, "Jane")
    res7: Boolean = false
    @ Person(1, "John") =/= Person(2, "Jane")
    res8: Boolean = true

    Conclusion

    Scalaz === 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.

    Scalaz Types of Polymorphism

    Polymorphism is a programming language feature that allows one interface to be used for a general class of actions.[1] Scalaz makes extensive use of ad-hoc polymorphism to provide its set of goodies. In this post I’ll cover ad-hoc polymorphism in detail and show you how you can implement ad-hoc polymorphism in Scala. I’ll also talk about parametric, and subtype polymorphism.

    Parametric Polymorphism

    In parametric polymorphism, the behavior of the function does not depend upon the type of the arguments passed to it. More formally[2],

    Parametric polymorphism refers to when the type of a value contains one or more (unconstrained) type variables, so that the value may adopt any type that results from substituting those variables with concrete types.

    1
    2
    3
    4
    5
    6
    7
    8
    scala> def head[A](xs: List[A]) = xs(0)
    head: [A](xs: List[A])A

    scala> head(List(1, 2, 3))
    res0: Int = 1

    scala> head(List("a", "b", "c"))
    res1: String = a

    Here, the argument xs has an unconstrained type A which can be anything and yet head would work. Then we call head with lists of concrete type Int, and String resulting in xs being of type List[Int] and List[String].

    Subtype Polymorphism

    Subtype polymorphism involves inheritance. More formally[3],

    Subtype polymorphism is a form of type polymorphism in which a subtype is a data-type that is related to another data-type (the super-type) by some notion of substitutability.

    As an example[4], consider a trait Plus which lets its subtype add itself with another of the same type.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    scala> trait Plus[A] {
    | def plus(a2: A): A
    | }
    defined trait Plus

    scala> def plus[A <: Plus[A]](a1: A, a2: A): A = a1.plus(a2)
    plus: [A <: Plus[A]](a1: A, a2: A)A

    scala> case class Currency(amount: Float, code: String) extends Plus[Currency] {
    | override def plus(other: Currency) = Currency(this.amount + other.amount, this.code)
    | }
    defined class Currency

    scala> case class Kilogram(amount: Float) extends Plus[Kilogram] {
    | override def plus(other: Kilogram) = Kilogram(this.amount + other.amount)
    | }
    defined class Kilogram

    scala> plus(Currency(1, "USD"), Currency(1, "USD"))
    res4: Currency = Currency(2.0,USD)

    scala> plus(Kilogram(1), Kilogram(1))
    res5: Kilogram = Kilogram(2.0)

    The function plus[A <: Plus[A]] will work only with those arguments that are subtype of Plus. This is restrictive because for this to work, the trait needs to be mixed in at the time of defining whatever concrete type A represents.

    Ad-hoc Polymorphism

    In ad-hoc polymorphism the behavior of the function depends on what the type of the argument is. More formally[5],

    Ad-hoc polymorphism refers to when a value is able to adopt any one of several types because it, or a value it uses, has been given a separate definition for each of those types.

    The simplest way to do ad-hoc polymorphism is by overloading functions. For example, having plus(Int, Int), plus(Currency, Currency), etc. The other ways are by using type classes, and coercion.

    Type Classes

    I’ll rewrite the Plus[A] example using type classes:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    scala> case class Currency(amount: Float, code: String)
    defined class Currency

    scala> case class Kilogram(amount: Float)
    defined class Kilogram

    scala> trait Plus[A] {
    | def plus(a:A, b: A): A
    | }
    defined trait Plus

    scala> object Plus {
    | implicit object CurrencyPlus extends Plus[Currency]{
    | override def plus(a: Currency, b: Currency): Currency = Currency(a.amount + b.amount, a.code)
    | }
    | implicit object KilogramPlus extends Plus[Kilogram] {
    | override def plus(a: Kilogram, b: Kilogram): Kilogram = Kilogram(a.amount + b.amount)
    | }
    | }
    defined object Plus

    scala> import Plus._
    import Plus._

    scala> def plus[A](a: A, b: A)(implicit p: Plus[A]) = p.plus(a, b)
    plus: [A](a: A, b: A)(implicit p: Plus[A])A

    scala> plus(Currency(1, "USD"), Currency(1, "USD"))
    res0: Currency = Currency(2.0,USD)

    scala> plus(Kilogram(1), Kilogram(1))
    res1: Kilogram = Kilogram(2.0)

    Relating the above implementation to the formal definition, the implicit p was able to adopt one of CurrencyPlus or KilogramPlus depending on what arguments were passed. Thus the behavior of plus is polymorphic as its behavior comes from the definition of each of the types.

    Coercion

    The other way to implement ad-hoc polymorphism is coercion. Coercion refers to implicitly converting the argument into a type that the function expects. Here’s an example modeled around scala.runtime.RichInt:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    scala> class AwesomeInt(val self: Int) {
    | def absolute: Int = math.abs(self)
    | }
    defined class AwesomeInt

    scala> object AwesomeInt {
    | import scala.language.implicitConversions
    | implicit def asAwesomeInt(x: Int): AwesomeInt = new AwesomeInt(x)
    | }
    defined object AwesomeInt

    scala> import AwesomeInt._
    import AwesomeInt._

    scala> -1.absolute
    res0: Int = 1

    The absolute method is defined in AwesomeInt but what we have is a plain old Int. This Int gets transformed into an AwesomeInt automagically because we have an implicit conversion within scope. The Int was coerced into an AwesomeInt.

    So we see how ad-hoc polymorphism allows us to extend classes to whose code we don’t have access. We defined absolute to work with Int which comes from the Scala core library.

    Higher-Kinded Types (HKT)

    In the post where we generalized sum function, we generalized it to work with a List. What if we want to generalize it even further so that it can work with not just list but anything? Here’s what we want to achieve:

    1
    2
    3
    4
    5
    // we have this
    def sum[A](xs: List[A])(implicit m: Monoid[A]): A = ???

    // we want this
    def sum[M[_], A](xs: M[A])(implicit m: Monoid[A], f: FoldLeft[M]): A = ???

    The difference between the two is that the first version, although polymorphic over types for which we have monoids defined, is still heavily tied to List. The second version instead will work with type that is FoldLeft. We’ll expand upon the sum example[6]. We’ll need the monoids and we’ll need to add a FoldLeft to make sum more generic.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    scala> import scala.language.higherKinds
    import scala.language.higherKinds

    scala> trait Monoid[A] {
    | def mempty: A
    | def mappend(a: A, b: A): A
    | }
    defined trait Monoid

    scala> trait FoldLeft[F[_]] {
    | def foldLeft[A, B](xs: F[A], b: B, f: (B, A) => B): B
    | }
    defined trait FoldLeft

    scala> object FoldLeft {
    | implicit object FoldLeftList extends FoldLeft[List] {
    | def foldLeft[A, B](xs: List[A], b: B, f: (B, A) => B): B = xs.foldLeft(b)(f)
    | }
    | }
    defined object FoldLeft

    scala> object Monoid {
    | implicit object IntMonoid extends Monoid[Int] {
    | def mempty: Int = 0
    | def mappend(a: Int, b: Int) = a + b
    | }
    | }
    defined object Monoid

    scala> import Monoid._
    import Monoid._

    scala> import FoldLeft._
    import FoldLeft._

    scala> def sum[M[_], T](xs: M[T])(implicit m: Monoid[T], f: FoldLeft[M]): T = f.foldLeft(xs, m.mempty, m.mappend)
    sum: [M[_], T](xs: M[T])(implicit m: Monoid[T], implicit f: FoldLeft[M])T

    scala> sum(List(1, 2, 3))
    res0: Int = 6

    So, by using HKT, we can generalize across types.

    Pimp My Library

    You might wonder what the whole point of using so much polymorphism is. The answer is that it lets you inject new functionality into existing libraries without having access to their source code. To quote Martin Odersky[7]:

    There’s a fundamental difference between your own code and libraries of other people: You can change or extend your own code, but if you want to use some other libraries you have to take them as they are … Scala has implicit parameters and conversions. They can make existing libraries much more pleasant to deal with.

    So, by using all the polymorphism techniques, we can implement the “pimp my library” pattern.[8]

    The Pimp my Library Pattern suggests an approach for extending a library that nearly does everything that you need but just needs a little more. It assumes that you do not have source code for the library of interest.

    Conclusion

    The polymorphism capabilities provided by Scala allow Scalaz to provide its set of features. By using HKT we can write code that truly generalizes across multiple types. It might seem like a long-winded way to do something so simple but as codebase gets larger and larger, the features that Scalaz provides out-of-the-box really help in eliminating boilerplate code. We haven’t seen how to use Scalaz, yet. These posts serve as a foundation to understand how Scalaz does what it does.

    Scalaz Under the Hoods

    A lot of what Scalaz does is made possible by using ad-hoc polymorphism, traits, and implicits. I’ll explain how this works by borrowing from Nick Partridge’s talk on Scalaz.

    Motivating Example

    Let’s begin with a simple sum function that adds together all the elements in a List[Int].

    1
    2
    scala> def sum(xs: List[Int]): Int = xs.foldLeft(0)( _ + _ )
    defined function sum

    The sum function above works only with List[Int]. If we want to sum together a List[Double], List[Float], or a List[String], we’d need a new implementation of sum. Our goal is to make sum function general so it would work with any of these.

    Step 1 - Monoid

    The first step towards generalizing sum is by using a monoid. A monoid is an algebraic structure with a single associative binary operation and an identity element.[1]. Since we are working with a List[Int], let’s create an IntMonoid.

    1
    2
    3
    4
    5
    6
    7
    8
    scala> object IntMonoid {
    def mempty: Int = 0
    def mappend(a: Int, b: Int): Int = a + b
    }
    defined object IntMonoid

    scala> def sum(xs: List[Int]) = xs.foldLeft(IntMonoid.mempty)(IntMonoid.mappend)
    defined function sum

    mempty is the identity or the zero value, and mappend is the binary operation which produces another Int i.e. another value in the set. These names come from Haskell[2].

    Step 2 - Generalizing the Monoid

    Next, we’ll generalize the monoid by creating a Monoid[A] so that IntMonoid is just a monoid on Int.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    scala> trait Monoid[A] {
    def mempty: A
    def mappend(a: A, b: A): A
    }
    defined trait Monoid

    scala> object IntMonoid extends Monoid[Int] {
    def mempty: Int = 0
    def mappend(a: Int, b: Int) = a + b
    }
    defined object IntMonoid

    scala> def sum[A](xs: List[A], m: Monoid[A]): A = xs.foldLeft(m.mempty)(m.mappend)
    defined function sum

    scala> sum(List(1, 2, 3), IntMonoid)
    res3: Int = 6

    What we’ve done is create a general-purpose sum function whose working depends upon which monoid is passed to it. Now we can very easily sum a List[String] or a List[Double] by adding a corresponding monoid.

    Step 3 - Make the Monoid Implicit

    Next, we’ll make the monoid an implicit parameter to our sum function. We’ll also package our IntMonoid into a Monoid companion object and make it implicit. The reason for doing this is how Scala compiler resolves implicit values; it’ll look for implicit values in its scope. So, we bring IntMonoid within scope by importing from the Monoid companion object.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    scala> trait Monoid[A] {
    def mempty: A
    def mappend(a: A, b: A): A
    }
    defined trait Monoid

    scala> object Monoid {
    implicit object IntMonoid extends Monoid[Int] {
    def mempty: Int = 0
    def mappend(a: Int, b: Int) = a + b
    }
    }
    defined object Monoid

    scala> import Monoid._
    import Monoid._

    scala> def sum[A](xs: List[A])(implicit m: Monoid[A]): A = xs.foldLeft(m.mempty)(m.mappend)
    defined function sum

    scala> sum(List(1, 2, 3))
    res4: Int = 6

    So, what we’ve done is create a general-purpose sum function that works as long as there is a corresponding implicit monoid within scope. This is made possible by using ad-hoc polymorphism. I’ll cover ad-hoc polymorphism briefly in this post and defer providing a detailed explanation for a later post.

    Ad-hoc Polymorphism

    Ad-hoc polymorphism is a type of polymorphism in which polymorphic functions are invoked depending on the different argument types. One way to implement ad-hoc polymorphism that we already know about is function overloading where a different “version” of the function is invoked depending on the type of arguments. This is what we’ve done in the post where there is only a single function but an implementation is provided for different types. In other words, sum only knows how to be invoked but the behavior is provided by monoids. Another way to implement ad-hoc polymorphism is coercion where the argument is converted into a type which the function expects.

    So, by using ad-hoc polymorphism, Scalaz is able to provide general-purpose functions over existing types. Ad-hoc polymorphism is flexible in the sense that it lets you extend even those classes for which you do not have access to the source code i.e. classes from other libraries, etc.

    Scalaz Introduction

    Motivation

    I’ve been using Scalaz for a while now and I remember not having any guides that provide a gentle introduction. It was a lot of scouring around, reading source code, and watching tech talks that gave me the understanding that I have now. This series of posts is intended at filling that gap by providing simple, step-by-step tutorials that will help you get productive quickly without compromising on the functional programming concepts.

    What is Scalaz?

    The documentation for Scalaz (pronounced Scala-zee or Scala-zed) states:

    Scalaz is a Scala library for functional programming.
    It provides purely functional data structures to complement those from the Scala standard library. It defines a set of foundational type classes (e.g. Functor, Monad) and corresponding instances for a large number of data structures.

    In a nutshell, Scalaz aims to do three things:

  • Provide new datatypes that are not present in the core Scala library
  • Provide new operations on existing types a.k.a. pimp the library
  • Provide general-purpose functions so that you don't have to re-write them
  • I’ll provide a quick example of each of these without going into any details.

    New Datatypes

    1
    2
    3
    4
    5
    6
    7
    8
    scala> import scalaz._
    import scalaz._

    scala> import Scalaz._
    import Scalaz._

    scala> NonEmptyList.nels(1, 2, 3)
    res0: scalaz.NonEmptyList[Int] = NonEmpty[1,2,3]

    Here we are creating a NonEmptyList which is a list that is guaranteed to have atleast one element i.e. it’s never empty.

    New Operations on Existing Types

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    scala> import scalaz._
    import scalaz._

    scala> import Scalaz._
    import Scalaz._

    scala> val o = Option(3)
    o: Option[Int] = Some(3)

    // Scalaz way
    scala> o some { _ + 1 } none { 0 }
    res0: Int = 4

    // Scala way
    scala> o.fold(0)( _ + 1 )
    res1: Int = 4

    The first way of extracting value from an Option comes from Scalaz and is much more expressive compared to using fold from Scala standard library.

    General-Purpose Functions

    1
    2
    3
    4
    5
    6
    7
    8
    scala> import scalaz._
    import scalaz._

    scala> import Scalaz._
    import Scalaz._

    scala> List(1, 2, 3) |+| List(4, 5, 6)
    res0: List[Int] = List(1, 2, 3, 4, 5, 6)

    The |+| operator from Scalaz conveniently concatenated the two Lists together.