A casual trip to the Monad, through Scalaz

We had a meetup reading 2nd chapter of Reactive Programming with Scala and Akka last Friday.

The first half of this chapter explains what is functional programming in Scala. And the latter, through one of the most popular Scala library called Scalaz, the important concepts in functional programming; Functors, Applicative Functors, and Monads.

In this blog post, I will explain about my shallow understanding of those three handsome guys.

Disclaimer: the below is not thorough nor correct definitions of those concepts at all. It simply is a starting point for understanding them.

Functors, Applicative Functors, and Monads, for the first step

If you don’t know very much about functors, applicative functional, and monads (like me as a Scala newbie), maybe a table below could help understand them.

Who are you? does what, mainly in which method
Functor maps a value A in some container F map[B](f: A => B): F[B]
Applicative applies a method A => B in some container F
to a value A in another container F
ap[A,B](f: => F[A => B]): F[B]
Monad flatMaps a value A in some container F bind[A, B](f: A => F[B]): F[B]

Here, the word container means kind of an abstraction of a way of holding value. Option, List and Future are good examples of them in Scala language.

type how it holds value
Option[T] holds a value of type T (Some(value)), or nothing (None)
List[T] holds multiple values of type T.
(that is, homogeneous collection of type T)
Future[T] holds some concurrent block that will eventually return
the value of type T, or Throwable as a failure result.

NOTE: Strictly speaking, container should actually be called a type class. See Wikipaedia for further explanations.

And Monads flatMap (or bind), this flattens the nested container as a result of mapping.

Anyway for better understandings let’s check out their implemtation in Scalaz’s source code with some examples.

Implementations & Examples

  • Functor
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
// From Scalaz, details omitted

trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
...
}

object Functor {
def apply[F[_]](implicit F: Functor[F]): Functor[F] = F
}

class FunctorOps[F[_],A](val self: F[A])(implicit val F: Functor[F]) {
def map[B](f: A => B): F[B] = F.map(self)(f)
...
}

trait FunctorSyntax[F[_]] extends InvariantFunctorSyntax[F] {
implicit def ToFunctorOps[A](v: F[A]): FunctorOps[F, A] =
new FunctorOps[F,A](v)(FunctorSyntax.this.F)
def F: Functor[F]
}

// Examples

import scalaz._, Scalaz._

Functor[List].map(1 to 10) {_ + 1}
// List(2, ..., 11)

Functor[Option].map(Some(10)) {_ + 1}
// Some(11)
  • Applicative (Applicative extends Apply)
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
57
58
59
60
61
62
63
64
// From Scalaz, details omitted

trait Apply[F[_]] extends Functor[F] {
def ap[A,B](fa: => F[A])(f: => F[A => B]): F[B]
...
}

trait Applicative[F[_]] extends Apply[F] {
def point[A](a: => A): F[A]
def pure[A](a: => A): F[A] = point(a)
def map[A, B](fa: F[A])(f: A => B): F[B] = ap(fa)(point(f))
...
}

object Applicative {
def apply[F[_]](implicit F: Applicative[F]): Applicative[F] = F
}

class ApplicativeOps[F[_],A](val self: F[A])(implicit val F: Applicative[F]) {
...
}

trait ApplicativeSyntax[F[_]] extends ApplySyntax[F] {
implicit def ToApplicativeOps[A](v: F[A]): ApplicativeOps[F, A] =
new ApplicativeOps[F,A](v)(ApplicativeSyntax.this.F)
}

// Examples

import scalaz._, Scalaz._

List(1, 2, 4) <*> List({(_:Int) * 3})
// List(3, 6, 12)

List(1, 2, 4) <*> {(_:Int) * 3}.point[List]
// List(3, 6, 12)

// when you want to apply functions at a time
val values = List(1, 2, 4)
val funcs1 = List({(_:Int) * 3})
val funcs2 = List({(_:Int) + 3})

// verbose!
val resultUsingFlatMap: List[Int] =
funcs1.flatMap { func1 =>
funcs2.flatMap { func2 =>
values.map { value =>
(func1 andThen func2)(value)
}
}
}

// concise!
val resultUsingFor: List[Int] =
for {
value <- values
func1 <- funcs1
func2 <- funcs2
} yield (func1 andThen func2)(value)

// more concise!?
// <*> is an alias for ap
val resultUsingApplicative: List[Int] =
values <*> funcs1 <*> funcs2
  • Monad
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
// From Scalaz, details omitted

trait Bind[F[_]] extends Apply[F] {
def bind[A, B](fa: F[A])(f: A => F[B]): F[B]
def ap[A, B](fa: => F[A])(f: => F[A => B]): F[B]
}

trait Monad[F[_]] extends Applicative[F] with Bind[F] {
def ap[A, B](fa: => F[A])(f: => F[A => B]): F[B]
...
}

object Monad {
def apply[F[_]](implicit F: Monad[F]): Monad[F] = F
}

class MonadOps[F[_],A](val self: F[A])(implicit val F: Monad[F]) {
...
}

trait MonadSyntax[F[_]] extends ApplicativeSyntax[F] with BindSyntax[F] {
implicit def ToMonadOps[A](v: F[A]): MonadOps[F, A] =
new MonadOps[F,A](v)(MonadSyntax.this.F)
def F: Monad[F]
}

// Examples

import scalaz._, Scalaz._

val value = "126"
val map = Map(10 -> "ten", 42 -> "the answer")
val toIntOption: String => Option[Int] = value => try { value.toInt.some } catch { case e: NumberFormatException => None }
val toDivBy3Option: Int => Option[Int] = value => (value % 3 == 0) ? (value / 3).some | None

// verbose version
toIntOption(value).flatMap { intValue =>
toDivBy3Option(intValue).flatMap { divBy3Value =>
map.get(divBy3Value)
}
}

// for comprehension
for {
intValue <- toIntOption(value)
divBy3Value <- toDivBy3Option(intValue)
mappedValue <- map.get(divBy3Value)
} yield mappedValue

// with sexy operators
// >>= is an alias for bind
Monad[Option].point(value) >>= toIntOption >>= toDivBy3Option >>= map.get

But what are these XxxOps and XxxSyntax??? This is kind of what we call pimp my library pattern in Scala, to add methods on target class or trait without modifying it, using the power of implicit conversion.

Its basic structure in Scalaz can be simplified like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Original

trait OriginalOps(val self: Original) {
def additionalMethod = ...
}

trait Syntax {
implicit def ToOriginalOps(original: Original): OriginalOps =
new OriginalOps(original)
}

object Syntax extends Syntax

// usage
import Syntax._

val original = new Original
original.additionalMethod

By the way,

Is there any easy good way to write some fancy operators like "η", "⊛", or "∘", without simply copy-and-pasting them? Once in a while I feel like to indulge in using them with a bit of fear about Gestaltzerfall…

Other helpful resources

For those who want to dive more into functional programming…

Oneteam Inc. is hiring a Scala engineer for server-side development. Please visit HERE

Reading Reactive Programming with Scala and Akka - Chapter 1

Last week I held a small reading club to read Reactive Programming with Scala and Akka, written by Prasanna Kumar Sathyanarayanan and Suraj Atreya.

The book contains a lot of exciting topics about Scala, Functional Programming, Reactive Programming, and Akka. Thus highly recommended for anyone with Scala love.

This time we read chapter 1, “Introducing Reactive Programming”. And the below is what we’ve learned from there.

me.jpg

Contents

This chapter largely contains these three parts, briefing the concept of reactive programming.

  • What is Reactive Programming?
  • Other stuffs around Reactive Programming
  • Actual use case of Reactive Programming

So what is Reactive Programming?

(Although this chapter is named “Introducing Reactive Programming”, it rather seems to be explaining about Reactive Systems, or, Reactive Architecute?)

Core ideas that support Reactive Programming are, according to the book:

  • Responsive
  • Resilient / fault tolerant
  • Scalable
  • Message-driven

The book illustrates these words one by one, among which I appreciated the explanation of the resilience, where the author express a failure as a first-class event. This is more concrete and easy-to-understand rephrase of Akka’s “let it crash” philosophy. Yes, we have to handle failures gracefully, instead of trying to kick out or suppress them, as if they were non-existent.

For those 4 RP pillars above, these materials would be of great help

From them, we could additionally learn the difference between scalable and elastic.

Scalability itself, for example, can be achieved simply by engineer’s manually re-writing a config file and adding one new server to the load balancer. But to achieve the elasticity, those configuration must be done dynamically and automatically. (see “Elasticity” in Glossary of the Reactive Manifesto)


So something like this?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
           +-                    +--------------+
Goal | +----> |Responsiveness| <-----+
+- | +--------------+ |
| ^ |
+- +-----+----+ | +-------+-------+
| |Elasticity| <------------> | Resilience / |
| +----------+ | |Fault tolerance|
| ^ | +---------------+
Principles | +--------> | | ^
| | | | |
| | +-----+-----+ | |
| | |Scalability| | |
| | +-----------+ | |
+- | ^ | |
| | | |
+- | +--------+-------------+---------------+---------+
Method | +-+ (Akka) Message−Driven architecture |
+- +------------------------------------------------+

Around Reactive Programming

Functional programming, asynchronous programming, data streams, microservices, and RESTful services… Those terminologies are too much popular recently and I can hardly imagine a day without using those jargons in software engineers’ conversation. But how are they related to Reactive Programming?

In this multicore processor era, asynchronous programming paradigm is vital for creating reactive systems since single-threaded programming model cannot fully utilize all the cores. Side-effect-free (pure) functional programming can make asynchronous programming easier.

And from the software architecture perspective, when adhering to the principle of the Reactive Programming, the system can eventually form a microservice-like shape because microservice architecture too emphasize a system’s modularity, scalability, maintainability and resilience. So in a sense, microservice architecture is sort of a realization of reactive architecture. And RESTful interface can be very handy universal language for interaction between those modularized services.

Use cases

The book introduces two reactive applications:

  • IoT
  • Tumblr’s architecture

One of the participants made an interesting remark on IoT that IoT devices themselves can construct a dense population as an Internet-connecting entities like us human beings. Think about that with the outrageous growth of the number of the Internet users described in the beginning of this chapter, the amount of data flowing back and forth on the Internet will no doubt continue to increase. To tackle with this problem, Reactive Programming must play the most important role in software engineering.

A thought on reading technical book in foreign language in a reading circle

As a non-native English speaker, I always find difficulty reading through technical materials written in English to the end. But when we have somebody to study with, we can help each other and learn from each other, including outside the scope of the book.

Thanks to this book, with catchy title and contents suitable for both beginners and intermediates of the Scala language, I felt that this very first time was successful. I hope we can enjoy the following chapters, too.

Others

For those interested in the book:

PACKT publishing is offering a subscription plan, where you can read any software books published by PACKT at a very reasonable price each month. On top of that, yearly plan can include monthly tokens to freely download any one digital book! I will strongly recommend applying for this plan.

https://www.packtpub.com/packtlib

For those interested in software development with Scala:

Oneteam Inc. is now hiring server-side engineer. Please visit HERE