SlideShare a Scribd company logo
1 of 61
Download to read offline
Scala. From Zero to Hero.
Monads.
k.v.kozlov@gmail.com, 2016
Functions as Objects
What about functions?
In fact function values are treated as objects in Scala.
The function type A => B is just an abbreviation for the class
scala.Function1[A, B], which is deļ¬ned as follows.
package scala
trait Function1[A, B] {
def apply(x: A): B
}
So functions are objects with apply methods.
Functions as Objects
An anonymous function such as
(x: Int) => x * x
is expanded to:
{
class AnonFun extends Function1[Int, Int] {
def apply(x: Int) = x * x
}
new AnonFun
}
or, shorter, using anonymous class syntax:
new Function1[Int, Int] {
def apply(x: Int) = x * x
}
Functions as Objects
A function call, such as f(a, b), where f is a value of some class
type, is expanded to
f.apply(a, b)
So the OO-translation of
val f = (x: Int) => x * x
f(7)
would be
val f = new Function1[Int, Int] {
def apply(x: Int) = x * x
}
f.apply(7)
Case Classes
A case class deļ¬nition is similar to a normal class
deļ¬nition, except that it is preceded by the
modiļ¬er case. For example:
trait Expr
case class Number(n: Int) extends Expr
case class Sum(e1: Expr, e2: Expr) extends Expr
Like before, this deļ¬nes a trait Expr, and two
concrete subclasses
Number and Sum
Case Classes
It also implicitly deļ¬nes companion objects with apply
methods.
object Number {
def apply(n: Int) = new Number(n)
}
object Sum {
def apply(e1: Expr, e2: Expr) = new Sum(e1, e2)
}
so you can write Number(1) instead of new Number(1).
Pattern matching
Pattern matching is a generalization of switch from C/Java to
class hierarchies.
Itā€™s expressed in Scala using the keyword match.
Example
eval(Sum(Number(1), Number(2)))
def eval(e: Expr): Int = e match {
case Number(n) => n
case Sum(e1, e2) => eval(e1) + eval(e2)
}
Lists
The list is a fundamental data stucture in functional programming.
A list having x1, ...,xn as elements is written List(x1, ...,xn)
Example
val fruit = List(Ā«applesĀ», Ā«orangesĀ», Ā«pearsĀ»)
val nums = List(1, 2, 3, 4)
val diag3 = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1))
val empty = List()
There are two important differences between lists and arrays.
ā— List are imuttable - the elements of list cannot be changed
ā— Lists are recursive, while arrays are flat
Constructors of Lists
All lists are constructed from:
ā— The empty list Nil, and
ā— The constructor operation :: (pronounces cons):
x :: xs gives a new list with the first element x, followed
by the element of xs
Example
fruit = Ā«applesĀ» :: (Ā«orangesĀ» :: (Ā«pearsĀ» :: Nil))
nums = 1 :: (2 :: (3 :: (4 :: Nil)))
empty = Nil
Map
A simple way to define map is as follows:
abstract class List[T] { ...
def map[U](f: T => U): List[U] = this match {
case Nil => Nil
case x :: xs => f(x) :: xs.map(f)
}
Example
def scaleList(xs: List[Double], factor: Double) =
xs map (x => x * factor)
flatMap
abstract class List[T] {
def flatMap[U](f: T => List[U]): List[U] = this match {
case x :: xs => f(x) ++ xs.flatMap(f)
case Nil => Nil
}
}
Filter
This pattern is generalized by the method filter of the List class:
abstract class List[T] {
...
def filter(p: T => Boolean): List[T] = this match {
case Nil => Nil
case x :: xs => if (p(x)) x :: xs.filter(p) else xs.filter(p)
}
}
Example
def posElems(xs: List[Int]): List[Int] =
xs filter (x => x > 0)
For-Expression
Higher-order functions such as map, flatMap
or filter provide powerful constructs for
manipulating lists.
But sometimes the level of abstraction
required by these function make the program
difficult to understand.
In this case, Scala's for expression notation
can help.
For-Expression Example
Let person be a list of elements of class Person, with fields
name and age.
case class Person(name: String, age: Int)
To obtain the names of person over 20 years old, you can
write:
for ( p <- persons if p.age > 20 ) yield p.name
Which is equivalent to:
persons filter (p => p.age > 20) map (p => p.name)
The for-expression is similar to loops in imperative languages,
except that is builds a list of the result of all iterations.
Syntax of For
A for-expression is of the form:
for ( s ) yield e
where s is a sequence of generators and filters, and e is an expression whose value is
returned by an iteration.
ā—
A generator is of the form p <- e, where p is a pattern and e an expression whose value is a
collection.
ā—
A filter is of the form if f where f is a boolean expression.
ā—
The sequence must start with generator.
ā—
If there are several generators in the sequence, the last generators vary faster than the first.
Example
for {
i <- 1 until n
j <- 1 until i
if isPrime(i + j)
} yield (i, j)
Queries with for
case class Book(title: String, authors: List[String])
val books: List[Book] = List(
Book(title = ā€Structure and Interpretation of
Computer Programsā€,
authors = List(ā€Abelson, Haraldā€, ā€Sussman,
Gerald J.ā€)),
Book(title = ā€Introduction to Functional
Programmingā€,
authors = List(ā€Bird, Richardā€, ā€Wadler, Philā€)),
Book(title = ā€Effective Javaā€,
authors = List(ā€Bloch, Joshuaā€)),
Book(title = ā€Java Puzzlersā€,
authors = List(ā€Bloch, Joshuaā€, ā€Gafter, Nealā€)),
Book(title = ā€Programming in Scalaā€,
authors = List(ā€Odersky, Martinā€, ā€Spoon, Lexā€,
ā€Venners, Billā€)))
To find the names of all authors
who have written at least two
books present in the database:
for {
b1 <- books
b2 <- books
if b1.title < b2.title
a1 <- b1.authors
a2 <- b2.authors
if a1 == a2
} yield a1
For-Expressions and Higher-Order
Functions
The syntax of for is closely related to the higher-order
functions map, flatMap and filter.
First of all, these functions can all be defined in terms of for:
def map[T, U](xs: List[T], f: T => U): List[U] =
for (x <- xs) yield f(x)
def flatMap[T, U](xs: List[T], f: T => Iterable[U]): List[U] =
for (x <- xs; y <- f(x)) yield y
def filter[T](xs: List[T], p: T => Boolean): List[T] =
for (x <- xs if p(x)) yield x
And vice versa
Translation of For
In reality, the Scala compiler expresses for-
expression in terms of map, flatMap and a lazy
variant of filter.
1. A simple for expression
for (x <- e1) yield e2
is translated to
e1.map(x => e2)
Translation of For
2: A for-expression
for (x <- e1 if f; s) yield e2
where f is a ļ¬lter and s is a (potentially empty)
sequence of generators and ļ¬lters, is translated to
for (x <- e1.withFilter(x => f); s) yield e2
(and the translation continues with the new expression)
You can think of withFilter as a variant of filter that
does not produce an intermediate list, but instead
ļ¬lters the following map or flatMap function application.
Translation of For
3: A for-expression
for (x <- e1; y <- e2; s) yield e3
where s is a (potentially empty) sequence of
generators and ļ¬lters,
is translated into
e1.flatMap(x => for (y <- e2; s) yield e3)
(and the translation continues with the new
expression)
Example
Take the for-expression that computed pairs whose sum is
prime:
for {
i <- 1 until n
j <- 1 until i
if isPrime(i + j)
} yield (i, j)
Applying the translation scheme to this expression gives:
(1 until n).flatMap(i =>
(1 until i).withFilter(j => isPrime(i+j))
.map(j => (i, j)))
For and Databases
For example, books might not be a list, but a database stored on
some server.
As long as the client interface to the database deļ¬nes the methods
map, flatMap and withFilter, we can use the for syntax for querying
the database.
This is the basis of the Scala data base connection frameworks
ScalaQuery and Slick.
Similar ideas underly Microsoftā€™s LINQ
(for (c < -coffees;
if c.sales > 999
)yield c.nam e).run
select"CO F_NAM E"
from "CO FFEES"
w here "SALES" > 999
As soon as you understand Monads, you will understand that
this is a Monad, too.
{{alt: What if someone broke out of a hypothetical situation in
your room right now?}}
Monads
Data structures with map and flatMap seem to
be quite common.
In fact thereā€™s a name that describes this class
of a data structures together with some
algebraic laws that they should have.
They are called monads.
What is a Monad?
A monad M is a parametric type M[T] with two
operations, flatMap and unit, that have to satisfy
some laws.
trait M[T] {
def flatMap[U](f: T => M[U]): M[U]
}
def unit[T](x: T): M[T]
In the literature, flatMap is more commonly
called bind.
Examples of Monads
ā€“ List is a monad with unit(x) = List(x)
ā€“ Set is monad with unit(x) = Set(x)
ā€“ Option is a monad with unit(x) = Some(x)
ā€“ Generator is a monad with unit(x) = single(x)
ā€“ ā€¦......
flatMap is an operation on each of these
types, whereas unit in Scala is di erent forļ¬€
each monad.
Monads and map
map can be deļ¬ned for every monad as a
combination of flatMap and unit:
m map f
== m flatMap (x => unit(f(x)))
== m flatMap (f andThen unit)
Monad Laws
To qualify as a monad, a type has to satisfy
three laws:
Associativity
m flatMap f flatMap g == m flatMap (x => f(x) flatMap g)
Left unit
unit(x) flatMap f == f(x)
Right unit
m flatMap unit == m
The Option monad
sealed trait Option[A] {
def map[B](f: A => B): Option[B]
def flatMap[B](f: A => Option[B]): Option[B]
}
case class Some[A](a: A) extends Option[A]
case class None[A] extends Option[A]
The Option monad makes the possibility of
missing data explicit in the type system, while
hiding the boilerplate Ā«if non-nullĀ» logic
Checking Monad Laws
Letā€™s check the monad laws for Option.
Hereā€™s flatMap for Option:
abstract class Option[+T] {
def flatMap[U](f: T => Option[U]): Option[U] = this match
{
case Some(x) => f(x)
case None => None
}
}
Try
Try resembles Option, but instead of Some/None
there is a Success case with a value and a Failure
case that contains an exception:
abstract class Try[+T]
case class Success[T](x: T) extends Try[T]
case class Failure(ex: Exception) extends Try[Nothing]
Try is used to pass results of computations that
can fail with an exception between threads and
computers
Creating a Try
You can wrap up an arbitrary computation in a Try.
Try(expr) // gives Success(someValue) or Failure(someException)
Hereā€™s an implementation of Try:
object Try {
def apply[T](expr: => T): Try[T] =
try Success(expr)
catch {
case NonFatal(ex) => Failure(ex)
}
}
Composing Try
Just like with Option, Try-valued computations can be composed
in for
expresssions.
for {
x <- computeX
y <- computeY
} yield f(x, y)
If computeX and computeY succeed with results Success(x) and
Success(y), this will return Success(f(x, y)).
If either computation fails with an exception ex, this will return
Failure(ex).
Deļ¬nition of flatMap and map on Try
abstract class Try[T] {
def flatMap[U](f: T => Try[U]): Try[U] = this match {
case Success(x) => try f(x) catch { case NonFatal(ex) => Failure(ex) }
case fail: Failure => fail
}
def map[U](f: T => U): Try[U] = this match {
case Success(x) => Try(f(x))
case fail: Failure => fail
}
}
The Try monad makes the possibility of errors explicit in
the type system, while hiding the boilerplate Ā«try/catchĀ»
logic
We have seen that for-expressions are useful not only for collections. Many other types
also deļ¬ne map,flatMap, and withFilter operations and with them for-expressions.
Examples: Generator, Option, Try.
Many of the types deļ¬ning flatMap are monads.
(If they also deļ¬ne withFilter, they are called ā€œmonads with zeroā€).
The three monad laws give useful guidance in the design of library APIs.
Lets play a simple game:
trait Adventure {
def collectCoins(): List[Coin]
def buyTreasure(coins: List[Coin]): Treasure
}
val adventure = Adventure()
val coins = adventure.collectCoins()
val treasure = adventure.buyTreasure(coins)
Actions may fail
def collectCoins(): List[Coin] = {
if (eatenByMonster(this))
throw new GameOverException(ā€œOoopsā€)
List(Gold, Gold, Silver)
}
def buyTreasure(coins: List[Coin]): Treasure = {
if (coins.sumBy(_.value) < treasureCost)
throw new GameOverException(ā€œNice try!ā€)
Diamond
}
val adventure = Adventure()
val coins = adventure.collectCoins()
val treasure = adventure.buyTreasure(coins)
Sequential composition of actions
that may fail
val adventure = Adventure()
val coins = adventure.collectCoins()
// block until coins are collected
// only continue if there is no exception
val treasure = adventure.buyTreasure(coins)
// block until treasure is bought
// only continue if there is no exception
Expose possibility of failure in the
types, honestly
T => S
T => Try[S]
Making failure evident intypes
import scala.util.{Try, Success, Failure}
abstract class Try[T]
case class Success[T](elem: T) extends Try[T]
case class Failure(t: Throwable) extends Try[Nothing]
object Try {
def apply[T](r: =>T): Try[T] = {
try { Success(r) }
catch { case t => Failure(t) }
}
trait Adventure {
def collectCoins(): Try[List[Coin]]
def buyTreasure(coins: List[Coin]): Try[Treasure]
}
Dealing with failure explicitly
val adventure = Adventure()
val coins: Try[List[Coin]] = adventure.collectCoins()
val treasure: Try[Treasure] = coins match {
case Success(cs) adventure.buyTreasure(cs)ā‡’
case failure @ Failure(t) failureā‡’
}
Noise reduction
val adventure = Adventure()
val treasure: Try[Treasure] =
adventure.collectCoins().flatMap(coins {ā‡’
adventure.buyTreasure(coins)
})
val treasure: Try[Treasure] = for {
coins <- adventure.collectCoins()
treasure <- buyTreasure(coins)
} yield treasure
Amonad that handles exceptions.
Try[T]
The Try monad makes the possibility of errors
explicit in the type system, while hiding the
boilerplate Ā«try/catchĀ» logic
trait Socket {
def readFromMemory(): Array[Byte]
def sendToEurope(packet: Array[Byte]): Array[Byte]
}
val socket = Socket()
val packet = socket.readFromMemory()
val confirmation = socket.sendToEurope(packet)
Timings for various operations on
a typical PC
val socket = Socket()
val packet = socket.readFromMemory()
// block for 50,000 ns
// only continue if there is no exception
val confirmation = socket.sendToEurope(packet)
// block for 150,000,000 ns
// only continue if there is no exception
Lets translate this into human terms. 1 nanosecond ā†’ 1 second
val socket = Socket()
val packet = socket.readFromMemory()
// block for 3 days
// only continue if there is no exception
val confirmation = socket.sendToEurope(packet)
// block for 5 years
// only continue if there is no exception
Futures asynchronously notify
consumers
Future[T]
A monad that handles
exceptions and latency
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
trait Future[T] {
def onComplete(callback: Try[T] Unit)ā‡’
(implicit executor: ExecutionContext): Unit
}
Futures asynchronously notify
consumers
import scala.concurrent._
trait Future[T] {
def onComplete(callback: Try[T] Unit)ā‡’
(implicit executor: ExecutionContext): Unit
}
trait Socket {
def readFromMemory(): Future[Array[Byte]]
def sendToEurope(packet: Array[Byte]): Future[Array[Byte]]
}
Sendpackets using futures
val socket = Socket()
val packet: Future[Array[Byte]] =
socket.readFromMemory()
packet onComplete {
case Success(p) {ā‡’
val confirmation: Future[Array[Byte]] =
socket.sendToEurope(p)
}
case Failure(t) => ā€¦
}
Creating Futures
// Starts an asynchronous computation
// and returns a future object to which you
// can subscribe to be notified when the
// future completes
object Future {
def apply(body: T)ā‡’
(implicit context: ExecutionContext): Future[T]
}
Creating Futures
import scala.concurrent.ExecutionContext.Implicits.global
import akka.serializer._
val memory = Queue[EMailMessage](
EMailMessage(from = ā€œErikā€, to = ā€œRolandā€),
EMailMessage(from = ā€œMartinā€, to = ā€œErikā€),
EMailMessage(from = ā€œRolandā€, to = ā€œMartinā€))
def readFromMemory(): Future[Array[Byte]] = Future {
val email = queue.dequeue()
val serializer = serialization.findSerializerFor(email)
serializer.toBinary(email)
}
Some Other Useful Monads
ā— The List monad makes nondeterminism explicit in the type
system, while hiding the boilerplate of nested for-loops.
ā— The Promise monad makes asynchronous computation
explicit in the type system, while hiding the boilerplate of
threading logic
ā— The Transaction monad (non-standard) makes
transactionality explicit in the type system, while hiding the
boilerplate of invoking rollbacks
ā— ā€¦ and more. Use monads wherever possible to keep your
code clean!
Future[T] and Try[T] are dual
trait Future[T] {
def OnComplete[U](func: Try[T] U)ā‡’
(implicit ex: ExecutionContext): Unit
}
Lets simplify:
(Try[T] Unit) Unitā‡’ ā‡’
Future[T] and Try[T] are dual
(Try[T] Unit) Unitā‡’ ā‡’
Reverse:
Unit (Unit Try[T])ā‡’ ā‡’
Simplify:
() (() Try[T])ā‡’ ā‡’ ā‰ˆ Try[T]
Future[T] and Try[T] are dual
Receive result of type Try[T] by passing
callback (Try[T] Unit)ā‡’ to method
def asynchronous(): Future[T] = { ā€¦ }
Receive result of type Try[T] by blocking
until method returns
def synchronous(): Try[T] = { ā€¦ }
Iterable[T]
trait Iterable[T] {
def iterator(): Iterator[T]
}
trait Iterator[T] {
def hasNext: Boolean
def next(): T
}
() (() Try[Option[T]])ā‡’ ā‡’
Iterable[T] vs Observables[T]
() (() Try[Option[T]])ā‡’ ā‡’
Reverse:
(Try[Option[T]] Unit) Unitā‡’ ā‡’
Simplify:
( T Unitā‡’
, Throwable Unitā‡’
, () Unitā‡’
) Unitā‡’
( T Unit,ā‡’
, Throwable Unitā‡’
, () Unitā‡’
) Unitā‡’
trait Observable[T] {
def Subscribe(observer: Observer[T]): Subscription
}
trait Observer[T] {
def onNext(value: T): Unit
def onError(error: Throwable): Unit
def onCompleted(): Unit
}
trait Subscription {
def unsubscribe(): Unit
}
Hello Observables
More INFO
ā— Functional Programming Principles in Scala
https://www.coursera.org/course/progfun
ā— Principles of Reactive Programming
https://www.coursera.org/course/reactive
ā— Programming Languages https://www.coursera.org/course/proglang
ā— Paradigms of Computer Programming
https://www.edx.org/course/louvainx/louvainx-louv1-01x-paradigms-compu
ter-1203
ā— Functional Reactive Programming & ClojureScript
https://www.youtube.com/watch?v=R4sTvHXkToQ&list=PL6JL99ajzlXU
bXUY0nwWr2imcrhJHT3Z7
ā— An Introduction to Functional Reactive Programming
https://www.youtube.com/watch?v=ZOCCzDNsAtI
ā— The reactive manifesto http://www.reactivemanifesto.org/
Frp2016 3

More Related Content

What's hot

Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Philip Schwarz
Ā 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala Knoldus Inc.
Ā 
Purely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaPurely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaVladimir Kostyukov
Ā 
Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?Lucas Witold Adamus
Ā 
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Philip Schwarz
Ā 
R short-refcard
R short-refcardR short-refcard
R short-refcardconline
Ā 
Abstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generatorsAbstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generatorsPhilip Schwarz
Ā 
R reference card
R reference cardR reference card
R reference cardHesher Shih
Ā 
Data transformation-cheatsheet
Data transformation-cheatsheetData transformation-cheatsheet
Data transformation-cheatsheetDieudonne Nahigombeye
Ā 
Monoids - Part 2 - with examples using Scalaz and Cats
Monoids - Part 2 - with examples using Scalaz and CatsMonoids - Part 2 - with examples using Scalaz and Cats
Monoids - Part 2 - with examples using Scalaz and CatsPhilip Schwarz
Ā 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Philip Schwarz
Ā 
Functor Composition
Functor CompositionFunctor Composition
Functor CompositionPhilip Schwarz
Ā 
Rewriting Java In Scala
Rewriting Java In ScalaRewriting Java In Scala
Rewriting Java In ScalaSkills Matter
Ā 

What's hot (18)

Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3
Ā 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
Ā 
Purely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaPurely Functional Data Structures in Scala
Purely Functional Data Structures in Scala
Ā 
Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?
Ā 
Scala collections
Scala collectionsScala collections
Scala collections
Ā 
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Ā 
JAVA PROGRAMMING - The Collections Framework
JAVA PROGRAMMING - The Collections Framework JAVA PROGRAMMING - The Collections Framework
JAVA PROGRAMMING - The Collections Framework
Ā 
Language R
Language RLanguage R
Language R
Ā 
R short-refcard
R short-refcardR short-refcard
R short-refcard
Ā 
Abstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generatorsAbstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generators
Ā 
Data import-cheatsheet
Data import-cheatsheetData import-cheatsheet
Data import-cheatsheet
Ā 
R reference card
R reference cardR reference card
R reference card
Ā 
Data transformation-cheatsheet
Data transformation-cheatsheetData transformation-cheatsheet
Data transformation-cheatsheet
Ā 
iPython
iPythoniPython
iPython
Ā 
Monoids - Part 2 - with examples using Scalaz and Cats
Monoids - Part 2 - with examples using Scalaz and CatsMonoids - Part 2 - with examples using Scalaz and Cats
Monoids - Part 2 - with examples using Scalaz and Cats
Ā 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
Ā 
Functor Composition
Functor CompositionFunctor Composition
Functor Composition
Ā 
Rewriting Java In Scala
Rewriting Java In ScalaRewriting Java In Scala
Rewriting Java In Scala
Ā 

Similar to Frp2016 3

Functional Programming by Examples using Haskell
Functional Programming by Examples using HaskellFunctional Programming by Examples using Haskell
Functional Programming by Examples using Haskellgoncharenko
Ā 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2Hang Zhao
Ā 
Edsc 304 lesson 1
Edsc 304 lesson 1Edsc 304 lesson 1
Edsc 304 lesson 1urenaa
Ā 
Practical cats
Practical catsPractical cats
Practical catsRaymond Tay
Ā 
Lesson 1
Lesson 1Lesson 1
Lesson 1urenaa
Ā 
Lesson 1
Lesson 1Lesson 1
Lesson 1urenaa
Ā 
Introducing scala
Introducing scalaIntroducing scala
Introducing scalaMeetu Maltiar
Ā 
Scala Bootcamp 1
Scala Bootcamp 1Scala Bootcamp 1
Scala Bootcamp 1Knoldus Inc.
Ā 
Reference card for R
Reference card for RReference card for R
Reference card for RDr. Volkan OBAN
Ā 
Short Reference Card for R users.
Short Reference Card for R users.Short Reference Card for R users.
Short Reference Card for R users.Dr. Volkan OBAN
Ā 
TI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsTI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsEelco Visser
Ā 
R command cheatsheet.pdf
R command cheatsheet.pdfR command cheatsheet.pdf
R command cheatsheet.pdfNgcnh947953
Ā 
@ R reference
@ R reference@ R reference
@ R referencevickyrolando
Ā 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed worldDebasish Ghosh
Ā 
Principles of functional progrmming in scala
Principles of functional progrmming in scalaPrinciples of functional progrmming in scala
Principles of functional progrmming in scalaehsoon
Ā 
Introduction to Functional Languages
Introduction to Functional LanguagesIntroduction to Functional Languages
Introduction to Functional Languagessuthi
Ā 

Similar to Frp2016 3 (20)

Functional Programming by Examples using Haskell
Functional Programming by Examples using HaskellFunctional Programming by Examples using Haskell
Functional Programming by Examples using Haskell
Ā 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
Ā 
Edsc 304 lesson 1
Edsc 304 lesson 1Edsc 304 lesson 1
Edsc 304 lesson 1
Ā 
Practical cats
Practical catsPractical cats
Practical cats
Ā 
Lesson 1
Lesson 1Lesson 1
Lesson 1
Ā 
Lesson 1
Lesson 1Lesson 1
Lesson 1
Ā 
Introducing scala
Introducing scalaIntroducing scala
Introducing scala
Ā 
Statistics lab 1
Statistics lab 1Statistics lab 1
Statistics lab 1
Ā 
Scala Bootcamp 1
Scala Bootcamp 1Scala Bootcamp 1
Scala Bootcamp 1
Ā 
Introduction to R
Introduction to RIntroduction to R
Introduction to R
Ā 
Scala Introduction
Scala IntroductionScala Introduction
Scala Introduction
Ā 
Reference card for R
Reference card for RReference card for R
Reference card for R
Ā 
Short Reference Card for R users.
Short Reference Card for R users.Short Reference Card for R users.
Short Reference Card for R users.
Ā 
TI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsTI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class Functions
Ā 
R command cheatsheet.pdf
R command cheatsheet.pdfR command cheatsheet.pdf
R command cheatsheet.pdf
Ā 
@ R reference
@ R reference@ R reference
@ R reference
Ā 
purrr.pdf
purrr.pdfpurrr.pdf
purrr.pdf
Ā 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
Ā 
Principles of functional progrmming in scala
Principles of functional progrmming in scalaPrinciples of functional progrmming in scala
Principles of functional progrmming in scala
Ā 
Introduction to Functional Languages
Introduction to Functional LanguagesIntroduction to Functional Languages
Introduction to Functional Languages
Ā 

Recently uploaded

Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
Ā 
办ē†å­¦ä½čƁ(UQę–‡å‡­čƁ书)ę˜†å£«å…°å¤§å­¦ęƕäøščÆęˆē»©å•åŽŸē‰ˆäø€ęØ”äø€ę ·
办ē†å­¦ä½čƁ(UQę–‡å‡­čƁ书)ę˜†å£«å…°å¤§å­¦ęƕäøščÆęˆē»©å•åŽŸē‰ˆäø€ęØ”äø€ę ·åŠžē†å­¦ä½čƁ(UQę–‡å‡­čƁ书)ę˜†å£«å…°å¤§å­¦ęƕäøščÆęˆē»©å•åŽŸē‰ˆäø€ęØ”äø€ę ·
办ē†å­¦ä½čƁ(UQę–‡å‡­čƁ书)ę˜†å£«å…°å¤§å­¦ęƕäøščÆęˆē»©å•åŽŸē‰ˆäø€ęØ”äø€ę ·umasea
Ā 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptrcbcrtm
Ā 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
Ā 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
Ā 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
Ā 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
Ā 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
Ā 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
Ā 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
Ā 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
Ā 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
Ā 
GOING AOT WITH GRAALVM ā€“ DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM ā€“ DEVOXX GREECE.pdfGOING AOT WITH GRAALVM ā€“ DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM ā€“ DEVOXX GREECE.pdfAlina Yurenko
Ā 
Dealing with Cultural Dispersion ā€” Stefano Lambiase ā€” ICSE-SEIS 2024
Dealing with Cultural Dispersion ā€” Stefano Lambiase ā€” ICSE-SEIS 2024Dealing with Cultural Dispersion ā€” Stefano Lambiase ā€” ICSE-SEIS 2024
Dealing with Cultural Dispersion ā€” Stefano Lambiase ā€” ICSE-SEIS 2024StefanoLambiase
Ā 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
Ā 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
Ā 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
Ā 

Recently uploaded (20)

Hot Sexy call girls in Patel NagaršŸ” 9953056974 šŸ” escort Service
Hot Sexy call girls in Patel NagaršŸ” 9953056974 šŸ” escort ServiceHot Sexy call girls in Patel NagaršŸ” 9953056974 šŸ” escort Service
Hot Sexy call girls in Patel NagaršŸ” 9953056974 šŸ” escort Service
Ā 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
Ā 
办ē†å­¦ä½čƁ(UQę–‡å‡­čƁ书)ę˜†å£«å…°å¤§å­¦ęƕäøščÆęˆē»©å•åŽŸē‰ˆäø€ęØ”äø€ę ·
办ē†å­¦ä½čƁ(UQę–‡å‡­čƁ书)ę˜†å£«å…°å¤§å­¦ęƕäøščÆęˆē»©å•åŽŸē‰ˆäø€ęØ”äø€ę ·åŠžē†å­¦ä½čƁ(UQę–‡å‡­čƁ书)ę˜†å£«å…°å¤§å­¦ęƕäøščÆęˆē»©å•åŽŸē‰ˆäø€ęØ”äø€ę ·
办ē†å­¦ä½čƁ(UQę–‡å‡­čƁ书)ę˜†å£«å…°å¤§å­¦ęƕäøščÆęˆē»©å•åŽŸē‰ˆäø€ęØ”äø€ę ·
Ā 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.ppt
Ā 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
Ā 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
Ā 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Ā 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
Ā 
2.pdf Ejercicios de programaciĆ³n competitiva
2.pdf Ejercicios de programaciĆ³n competitiva2.pdf Ejercicios de programaciĆ³n competitiva
2.pdf Ejercicios de programaciĆ³n competitiva
Ā 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
Ā 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Ā 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
Ā 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
Ā 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
Ā 
GOING AOT WITH GRAALVM ā€“ DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM ā€“ DEVOXX GREECE.pdfGOING AOT WITH GRAALVM ā€“ DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM ā€“ DEVOXX GREECE.pdf
Ā 
Dealing with Cultural Dispersion ā€” Stefano Lambiase ā€” ICSE-SEIS 2024
Dealing with Cultural Dispersion ā€” Stefano Lambiase ā€” ICSE-SEIS 2024Dealing with Cultural Dispersion ā€” Stefano Lambiase ā€” ICSE-SEIS 2024
Dealing with Cultural Dispersion ā€” Stefano Lambiase ā€” ICSE-SEIS 2024
Ā 
Odoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting ServiceOdoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting Service
Ā 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Ā 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Ā 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
Ā 

Frp2016 3

  • 1. Scala. From Zero to Hero. Monads. k.v.kozlov@gmail.com, 2016
  • 2. Functions as Objects What about functions? In fact function values are treated as objects in Scala. The function type A => B is just an abbreviation for the class scala.Function1[A, B], which is deļ¬ned as follows. package scala trait Function1[A, B] { def apply(x: A): B } So functions are objects with apply methods.
  • 3. Functions as Objects An anonymous function such as (x: Int) => x * x is expanded to: { class AnonFun extends Function1[Int, Int] { def apply(x: Int) = x * x } new AnonFun } or, shorter, using anonymous class syntax: new Function1[Int, Int] { def apply(x: Int) = x * x }
  • 4. Functions as Objects A function call, such as f(a, b), where f is a value of some class type, is expanded to f.apply(a, b) So the OO-translation of val f = (x: Int) => x * x f(7) would be val f = new Function1[Int, Int] { def apply(x: Int) = x * x } f.apply(7)
  • 5. Case Classes A case class deļ¬nition is similar to a normal class deļ¬nition, except that it is preceded by the modiļ¬er case. For example: trait Expr case class Number(n: Int) extends Expr case class Sum(e1: Expr, e2: Expr) extends Expr Like before, this deļ¬nes a trait Expr, and two concrete subclasses Number and Sum
  • 6. Case Classes It also implicitly deļ¬nes companion objects with apply methods. object Number { def apply(n: Int) = new Number(n) } object Sum { def apply(e1: Expr, e2: Expr) = new Sum(e1, e2) } so you can write Number(1) instead of new Number(1).
  • 7. Pattern matching Pattern matching is a generalization of switch from C/Java to class hierarchies. Itā€™s expressed in Scala using the keyword match. Example eval(Sum(Number(1), Number(2))) def eval(e: Expr): Int = e match { case Number(n) => n case Sum(e1, e2) => eval(e1) + eval(e2) }
  • 8. Lists The list is a fundamental data stucture in functional programming. A list having x1, ...,xn as elements is written List(x1, ...,xn) Example val fruit = List(Ā«applesĀ», Ā«orangesĀ», Ā«pearsĀ») val nums = List(1, 2, 3, 4) val diag3 = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) val empty = List() There are two important differences between lists and arrays. ā— List are imuttable - the elements of list cannot be changed ā— Lists are recursive, while arrays are flat
  • 9. Constructors of Lists All lists are constructed from: ā— The empty list Nil, and ā— The constructor operation :: (pronounces cons): x :: xs gives a new list with the first element x, followed by the element of xs Example fruit = Ā«applesĀ» :: (Ā«orangesĀ» :: (Ā«pearsĀ» :: Nil)) nums = 1 :: (2 :: (3 :: (4 :: Nil))) empty = Nil
  • 10. Map A simple way to define map is as follows: abstract class List[T] { ... def map[U](f: T => U): List[U] = this match { case Nil => Nil case x :: xs => f(x) :: xs.map(f) } Example def scaleList(xs: List[Double], factor: Double) = xs map (x => x * factor)
  • 11. flatMap abstract class List[T] { def flatMap[U](f: T => List[U]): List[U] = this match { case x :: xs => f(x) ++ xs.flatMap(f) case Nil => Nil } }
  • 12. Filter This pattern is generalized by the method filter of the List class: abstract class List[T] { ... def filter(p: T => Boolean): List[T] = this match { case Nil => Nil case x :: xs => if (p(x)) x :: xs.filter(p) else xs.filter(p) } } Example def posElems(xs: List[Int]): List[Int] = xs filter (x => x > 0)
  • 13. For-Expression Higher-order functions such as map, flatMap or filter provide powerful constructs for manipulating lists. But sometimes the level of abstraction required by these function make the program difficult to understand. In this case, Scala's for expression notation can help.
  • 14. For-Expression Example Let person be a list of elements of class Person, with fields name and age. case class Person(name: String, age: Int) To obtain the names of person over 20 years old, you can write: for ( p <- persons if p.age > 20 ) yield p.name Which is equivalent to: persons filter (p => p.age > 20) map (p => p.name) The for-expression is similar to loops in imperative languages, except that is builds a list of the result of all iterations.
  • 15. Syntax of For A for-expression is of the form: for ( s ) yield e where s is a sequence of generators and filters, and e is an expression whose value is returned by an iteration. ā— A generator is of the form p <- e, where p is a pattern and e an expression whose value is a collection. ā— A filter is of the form if f where f is a boolean expression. ā— The sequence must start with generator. ā— If there are several generators in the sequence, the last generators vary faster than the first. Example for { i <- 1 until n j <- 1 until i if isPrime(i + j) } yield (i, j)
  • 16. Queries with for case class Book(title: String, authors: List[String]) val books: List[Book] = List( Book(title = ā€Structure and Interpretation of Computer Programsā€, authors = List(ā€Abelson, Haraldā€, ā€Sussman, Gerald J.ā€)), Book(title = ā€Introduction to Functional Programmingā€, authors = List(ā€Bird, Richardā€, ā€Wadler, Philā€)), Book(title = ā€Effective Javaā€, authors = List(ā€Bloch, Joshuaā€)), Book(title = ā€Java Puzzlersā€, authors = List(ā€Bloch, Joshuaā€, ā€Gafter, Nealā€)), Book(title = ā€Programming in Scalaā€, authors = List(ā€Odersky, Martinā€, ā€Spoon, Lexā€, ā€Venners, Billā€))) To find the names of all authors who have written at least two books present in the database: for { b1 <- books b2 <- books if b1.title < b2.title a1 <- b1.authors a2 <- b2.authors if a1 == a2 } yield a1
  • 17. For-Expressions and Higher-Order Functions The syntax of for is closely related to the higher-order functions map, flatMap and filter. First of all, these functions can all be defined in terms of for: def map[T, U](xs: List[T], f: T => U): List[U] = for (x <- xs) yield f(x) def flatMap[T, U](xs: List[T], f: T => Iterable[U]): List[U] = for (x <- xs; y <- f(x)) yield y def filter[T](xs: List[T], p: T => Boolean): List[T] = for (x <- xs if p(x)) yield x And vice versa
  • 18. Translation of For In reality, the Scala compiler expresses for- expression in terms of map, flatMap and a lazy variant of filter. 1. A simple for expression for (x <- e1) yield e2 is translated to e1.map(x => e2)
  • 19. Translation of For 2: A for-expression for (x <- e1 if f; s) yield e2 where f is a ļ¬lter and s is a (potentially empty) sequence of generators and ļ¬lters, is translated to for (x <- e1.withFilter(x => f); s) yield e2 (and the translation continues with the new expression) You can think of withFilter as a variant of filter that does not produce an intermediate list, but instead ļ¬lters the following map or flatMap function application.
  • 20. Translation of For 3: A for-expression for (x <- e1; y <- e2; s) yield e3 where s is a (potentially empty) sequence of generators and ļ¬lters, is translated into e1.flatMap(x => for (y <- e2; s) yield e3) (and the translation continues with the new expression)
  • 21. Example Take the for-expression that computed pairs whose sum is prime: for { i <- 1 until n j <- 1 until i if isPrime(i + j) } yield (i, j) Applying the translation scheme to this expression gives: (1 until n).flatMap(i => (1 until i).withFilter(j => isPrime(i+j)) .map(j => (i, j)))
  • 22. For and Databases For example, books might not be a list, but a database stored on some server. As long as the client interface to the database deļ¬nes the methods map, flatMap and withFilter, we can use the for syntax for querying the database. This is the basis of the Scala data base connection frameworks ScalaQuery and Slick. Similar ideas underly Microsoftā€™s LINQ (for (c < -coffees; if c.sales > 999 )yield c.nam e).run select"CO F_NAM E" from "CO FFEES" w here "SALES" > 999
  • 23. As soon as you understand Monads, you will understand that this is a Monad, too. {{alt: What if someone broke out of a hypothetical situation in your room right now?}}
  • 24. Monads Data structures with map and flatMap seem to be quite common. In fact thereā€™s a name that describes this class of a data structures together with some algebraic laws that they should have. They are called monads.
  • 25. What is a Monad? A monad M is a parametric type M[T] with two operations, flatMap and unit, that have to satisfy some laws. trait M[T] { def flatMap[U](f: T => M[U]): M[U] } def unit[T](x: T): M[T] In the literature, flatMap is more commonly called bind.
  • 26. Examples of Monads ā€“ List is a monad with unit(x) = List(x) ā€“ Set is monad with unit(x) = Set(x) ā€“ Option is a monad with unit(x) = Some(x) ā€“ Generator is a monad with unit(x) = single(x) ā€“ ā€¦...... flatMap is an operation on each of these types, whereas unit in Scala is di erent forļ¬€ each monad.
  • 27. Monads and map map can be deļ¬ned for every monad as a combination of flatMap and unit: m map f == m flatMap (x => unit(f(x))) == m flatMap (f andThen unit)
  • 28. Monad Laws To qualify as a monad, a type has to satisfy three laws: Associativity m flatMap f flatMap g == m flatMap (x => f(x) flatMap g) Left unit unit(x) flatMap f == f(x) Right unit m flatMap unit == m
  • 29. The Option monad sealed trait Option[A] { def map[B](f: A => B): Option[B] def flatMap[B](f: A => Option[B]): Option[B] } case class Some[A](a: A) extends Option[A] case class None[A] extends Option[A] The Option monad makes the possibility of missing data explicit in the type system, while hiding the boilerplate Ā«if non-nullĀ» logic
  • 30. Checking Monad Laws Letā€™s check the monad laws for Option. Hereā€™s flatMap for Option: abstract class Option[+T] { def flatMap[U](f: T => Option[U]): Option[U] = this match { case Some(x) => f(x) case None => None } }
  • 31. Try Try resembles Option, but instead of Some/None there is a Success case with a value and a Failure case that contains an exception: abstract class Try[+T] case class Success[T](x: T) extends Try[T] case class Failure(ex: Exception) extends Try[Nothing] Try is used to pass results of computations that can fail with an exception between threads and computers
  • 32. Creating a Try You can wrap up an arbitrary computation in a Try. Try(expr) // gives Success(someValue) or Failure(someException) Hereā€™s an implementation of Try: object Try { def apply[T](expr: => T): Try[T] = try Success(expr) catch { case NonFatal(ex) => Failure(ex) } }
  • 33. Composing Try Just like with Option, Try-valued computations can be composed in for expresssions. for { x <- computeX y <- computeY } yield f(x, y) If computeX and computeY succeed with results Success(x) and Success(y), this will return Success(f(x, y)). If either computation fails with an exception ex, this will return Failure(ex).
  • 34. Deļ¬nition of flatMap and map on Try abstract class Try[T] { def flatMap[U](f: T => Try[U]): Try[U] = this match { case Success(x) => try f(x) catch { case NonFatal(ex) => Failure(ex) } case fail: Failure => fail } def map[U](f: T => U): Try[U] = this match { case Success(x) => Try(f(x)) case fail: Failure => fail } } The Try monad makes the possibility of errors explicit in the type system, while hiding the boilerplate Ā«try/catchĀ» logic
  • 35. We have seen that for-expressions are useful not only for collections. Many other types also deļ¬ne map,flatMap, and withFilter operations and with them for-expressions. Examples: Generator, Option, Try. Many of the types deļ¬ning flatMap are monads. (If they also deļ¬ne withFilter, they are called ā€œmonads with zeroā€). The three monad laws give useful guidance in the design of library APIs.
  • 36. Lets play a simple game: trait Adventure { def collectCoins(): List[Coin] def buyTreasure(coins: List[Coin]): Treasure } val adventure = Adventure() val coins = adventure.collectCoins() val treasure = adventure.buyTreasure(coins)
  • 37. Actions may fail def collectCoins(): List[Coin] = { if (eatenByMonster(this)) throw new GameOverException(ā€œOoopsā€) List(Gold, Gold, Silver) } def buyTreasure(coins: List[Coin]): Treasure = { if (coins.sumBy(_.value) < treasureCost) throw new GameOverException(ā€œNice try!ā€) Diamond } val adventure = Adventure() val coins = adventure.collectCoins() val treasure = adventure.buyTreasure(coins)
  • 38. Sequential composition of actions that may fail val adventure = Adventure() val coins = adventure.collectCoins() // block until coins are collected // only continue if there is no exception val treasure = adventure.buyTreasure(coins) // block until treasure is bought // only continue if there is no exception
  • 39. Expose possibility of failure in the types, honestly T => S T => Try[S]
  • 40. Making failure evident intypes import scala.util.{Try, Success, Failure} abstract class Try[T] case class Success[T](elem: T) extends Try[T] case class Failure(t: Throwable) extends Try[Nothing] object Try { def apply[T](r: =>T): Try[T] = { try { Success(r) } catch { case t => Failure(t) } } trait Adventure { def collectCoins(): Try[List[Coin]] def buyTreasure(coins: List[Coin]): Try[Treasure] }
  • 41. Dealing with failure explicitly val adventure = Adventure() val coins: Try[List[Coin]] = adventure.collectCoins() val treasure: Try[Treasure] = coins match { case Success(cs) adventure.buyTreasure(cs)ā‡’ case failure @ Failure(t) failureā‡’ }
  • 42. Noise reduction val adventure = Adventure() val treasure: Try[Treasure] = adventure.collectCoins().flatMap(coins {ā‡’ adventure.buyTreasure(coins) }) val treasure: Try[Treasure] = for { coins <- adventure.collectCoins() treasure <- buyTreasure(coins) } yield treasure
  • 43. Amonad that handles exceptions. Try[T] The Try monad makes the possibility of errors explicit in the type system, while hiding the boilerplate Ā«try/catchĀ» logic
  • 44. trait Socket { def readFromMemory(): Array[Byte] def sendToEurope(packet: Array[Byte]): Array[Byte] } val socket = Socket() val packet = socket.readFromMemory() val confirmation = socket.sendToEurope(packet)
  • 45. Timings for various operations on a typical PC
  • 46. val socket = Socket() val packet = socket.readFromMemory() // block for 50,000 ns // only continue if there is no exception val confirmation = socket.sendToEurope(packet) // block for 150,000,000 ns // only continue if there is no exception Lets translate this into human terms. 1 nanosecond ā†’ 1 second val socket = Socket() val packet = socket.readFromMemory() // block for 3 days // only continue if there is no exception val confirmation = socket.sendToEurope(packet) // block for 5 years // only continue if there is no exception
  • 47. Futures asynchronously notify consumers Future[T] A monad that handles exceptions and latency import scala.concurrent._ import scala.concurrent.ExecutionContext.Implicits.global trait Future[T] { def onComplete(callback: Try[T] Unit)ā‡’ (implicit executor: ExecutionContext): Unit }
  • 48. Futures asynchronously notify consumers import scala.concurrent._ trait Future[T] { def onComplete(callback: Try[T] Unit)ā‡’ (implicit executor: ExecutionContext): Unit } trait Socket { def readFromMemory(): Future[Array[Byte]] def sendToEurope(packet: Array[Byte]): Future[Array[Byte]] }
  • 49. Sendpackets using futures val socket = Socket() val packet: Future[Array[Byte]] = socket.readFromMemory() packet onComplete { case Success(p) {ā‡’ val confirmation: Future[Array[Byte]] = socket.sendToEurope(p) } case Failure(t) => ā€¦ }
  • 50. Creating Futures // Starts an asynchronous computation // and returns a future object to which you // can subscribe to be notified when the // future completes object Future { def apply(body: T)ā‡’ (implicit context: ExecutionContext): Future[T] }
  • 51. Creating Futures import scala.concurrent.ExecutionContext.Implicits.global import akka.serializer._ val memory = Queue[EMailMessage]( EMailMessage(from = ā€œErikā€, to = ā€œRolandā€), EMailMessage(from = ā€œMartinā€, to = ā€œErikā€), EMailMessage(from = ā€œRolandā€, to = ā€œMartinā€)) def readFromMemory(): Future[Array[Byte]] = Future { val email = queue.dequeue() val serializer = serialization.findSerializerFor(email) serializer.toBinary(email) }
  • 52. Some Other Useful Monads ā— The List monad makes nondeterminism explicit in the type system, while hiding the boilerplate of nested for-loops. ā— The Promise monad makes asynchronous computation explicit in the type system, while hiding the boilerplate of threading logic ā— The Transaction monad (non-standard) makes transactionality explicit in the type system, while hiding the boilerplate of invoking rollbacks ā— ā€¦ and more. Use monads wherever possible to keep your code clean!
  • 53. Future[T] and Try[T] are dual trait Future[T] { def OnComplete[U](func: Try[T] U)ā‡’ (implicit ex: ExecutionContext): Unit } Lets simplify: (Try[T] Unit) Unitā‡’ ā‡’
  • 54. Future[T] and Try[T] are dual (Try[T] Unit) Unitā‡’ ā‡’ Reverse: Unit (Unit Try[T])ā‡’ ā‡’ Simplify: () (() Try[T])ā‡’ ā‡’ ā‰ˆ Try[T]
  • 55. Future[T] and Try[T] are dual Receive result of type Try[T] by passing callback (Try[T] Unit)ā‡’ to method def asynchronous(): Future[T] = { ā€¦ } Receive result of type Try[T] by blocking until method returns def synchronous(): Try[T] = { ā€¦ }
  • 56. Iterable[T] trait Iterable[T] { def iterator(): Iterator[T] } trait Iterator[T] { def hasNext: Boolean def next(): T } () (() Try[Option[T]])ā‡’ ā‡’
  • 57. Iterable[T] vs Observables[T] () (() Try[Option[T]])ā‡’ ā‡’ Reverse: (Try[Option[T]] Unit) Unitā‡’ ā‡’ Simplify: ( T Unitā‡’ , Throwable Unitā‡’ , () Unitā‡’ ) Unitā‡’
  • 58. ( T Unit,ā‡’ , Throwable Unitā‡’ , () Unitā‡’ ) Unitā‡’ trait Observable[T] { def Subscribe(observer: Observer[T]): Subscription } trait Observer[T] { def onNext(value: T): Unit def onError(error: Throwable): Unit def onCompleted(): Unit } trait Subscription { def unsubscribe(): Unit }
  • 60. More INFO ā— Functional Programming Principles in Scala https://www.coursera.org/course/progfun ā— Principles of Reactive Programming https://www.coursera.org/course/reactive ā— Programming Languages https://www.coursera.org/course/proglang ā— Paradigms of Computer Programming https://www.edx.org/course/louvainx/louvainx-louv1-01x-paradigms-compu ter-1203 ā— Functional Reactive Programming & ClojureScript https://www.youtube.com/watch?v=R4sTvHXkToQ&list=PL6JL99ajzlXU bXUY0nwWr2imcrhJHT3Z7 ā— An Introduction to Functional Reactive Programming https://www.youtube.com/watch?v=ZOCCzDNsAtI ā— The reactive manifesto http://www.reactivemanifesto.org/