The document provides an overview of the ZIO library, which provides purely functional data structures and abstractions for effectful programs using monads. It describes ZIO's IO data type, which represents effectful programs that may fail, run forever, or produce a value. It also covers ZIO concepts like Refs (immutable references), Promises (asynchronous values that can be set once), and Queues (asynchronous FIFO queues for producers and consumers).
8. The Scalaz8 effect is moved to a new
library Scalaz-zio with zero dependencies.
Good news!
9. What is ZIO?
ZIO provides purely functional data
structures with an abstraction for the
effectful programs using monads.
10. Effectful program
● Interaction with the real World
● Hard to reason about
● Hard to test
● Refactoring
● Programming without effects is useless
11. Properties of pure functions
Non-pure functions
def parseInt(s: String): Int = s.toInt
def addOne(x: Int): Int = Random.nextInt(x) + 1
def buyCoffee(cc: CreditCard): Coffee = {
val cup = new Coffee()
p.charge(cc, cup.price)
cup
}
12. Properties of pure functions
Non-pure functions
def parseInt(s: String): Int = s.toInt
def addOne(x: Int): Int = Random.nextInt(x) + 1
def buyCoffee(cc: CreditCard): Coffee = {
val cup = new Coffee()
p.charge(cc, cup.price)
cup
}
parseInt("Hello!")
[error] java.lang.NumberFormatException:
For input string: "Hello!"
NOT TOTAL!
13. Properties of pure functions
Non-pure functions
def parseInt(s: String): Int = s.toInt
def addOne(x: Int): Int = Random.nextInt(x) + 1
def buyCoffee(cc: CreditCard): Coffee = {
val cup = new Coffee()
p.charge(cc, cup.price)
cup
}
14. Properties of pure functions
Non-pure functions
def parseInt(s: String): Int = s.toInt
def addOne(x: Int): Int = Random.nextInt(x) + 1
def buyCoffee(cc: CreditCard): Coffee = {
val cup = new Coffee()
p.charge(cc, cup.price)
cup
}
addOne(10)
> 4
addOne(10)
> 6
addOne(10)
> 2
NON DETERMINISTIC!
15. Properties of pure functions
Non-pure functions
def parseInt(s: String): Int = s.toInt
def addOne(x: Int): Int = Random.nextInt(x) + 1
def buyCoffee(cc: CreditCard): Coffee = {
val cup = new Coffee()
p.charge(cc, cup.price)
cup
}
16. Properties of pure functions
Non-pure functions
def parseInt(s: String): Int = s.toInt
def addOne(x: Int): Int = Random.nextInt(x) + 1
def buyCoffee(cc: CreditCard): Coffee = {
val cup = new Coffee()
p.charge(cc, cup.price)
cup
}
SIDE EFFECT!
17. Properties of pure functions
Non-pure functions
def parseInt(s: String): Int = s.toInt
def addOne(x: Int): Int = Random.nextInt(x) + 1
def buyCoffee(cc: CreditCard): Coffee = {
val cup = new Coffee()
p.charge(cc, cup.price)
cup
}
SIDE EFFECT!
18. Properties of pure functions
Non-pure functions
def parseInt(s: String): Int = s.toInt
def addOne(x: Int): Int = Random.nextInt(x) + 1
def buyCoffee(cc: CreditCard): Coffee = {
val cup = new Coffee()
p.charge(cc, cup.price)
cup
}
def program(): = { }
19. Properties of pure functions
Non-pure functions
def parseInt(s: String): Int = s.toInt
def addOne(x: Int): Int = Random.nextInt(x) + 1
def buyCoffee(cc: CreditCard): Coffee = {
val cup = new Coffee()
p.charge(cc, cup.price)
cup
}
Pure functions
def parseInt(s: String): Option[Int] =
Try(s.toInt).toOption
def addOne(x: Int): Int = x + 1
def buyCoffee(cc: CreditCard): (Coffee, Charge) = {
val cup = new Coffee()
(cup, Charge(cc, cup.price))
}
def program(): = { }
20. Properties of pure functions
Pure functions
def parseInt(s: String): Option[Int] =
Try(s.toInt).toOption
def addOne(x: Int): Int = x + 1
def buyCoffee(cc: CreditCard): (Coffee, Charge) =
{
val cup = new Coffee()
(cup, Charge(cc, cup.price))
}
Non-pure functions
def parseInt(s: String): Int = s.toInt
def addOne(x: Int): Int = Random.nextInt(x) + 1
def buyCoffee(cc: CreditCard): Coffee = {
val cup = new Coffee()
p.charge(cc, cup.price)
cup
}
def program(): = { } def program(): = { }
21. Properties of pure functions
● Total
● Deterministic
● Free of side effects
23. What is IO[E, A] ?
IO is an immutable data structure that describes an
effectful program that may:
● fail with an E
● run forever
● produce a single A
24. What is IO[E, A] ?
parseInt("hello") //fails with NumberFormatExceptionIO.syncException(parseInt(str))
39. Usage of IO
In ZIO, every type has specific
features to solve different problems.
Each type is wrapped inside an IO.
Promise[E, A]
Ref[A]
Queue[A]
IO[E, A]
40. RTS: IO runtime system
IO is interpreted by the IO runtime system into
effectful interactions with the external world.
● unsafeRun
● In your application’s main function (App
provides this functionality automatically).
def main(args: Array[String]): Unit =
println("Hello")
def main(args: Array[String]): Unit =
unsafeRun(IO.sync(println("Hello")))
41. Ref
Ref is the equivalent of `var`
Ref has an AtomicReference to apply the
atomic operations on it.
43. Example
for {
counter <- Ref(0)
v <- counter.update(_ + 1)
} yield v
for {
counter <- Ref(0)
v <- counter.modify {
prev =>
val newValue = prev + 1
(s"previous value: $prev, next value is: $newValue", newValue)
}
_ <- IO.sync(println(v))
} yield ()
45. Promise
A Promise is an asynchronous variable that
can be set only once.
`error`: fails the promise with the specified error, which will be
propagated to all fibers waiting on the value of promise.
46. Promise
A Promise is an asynchronous variable that
can be set only once.
`complete`: completes the promise with the specified value.
47. Promise
By default the state of Promise is Pending, once it fails or completes
the state changes to Done.
`done`: completes the promise with the specified result.
A Promise is an asynchronous variable that
can be set only once.