copyright 2013 Trainologic LTD
Scalaz – The Good
Parts
2 copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• Scalaz is one of the famous/infamous libraries in Scala.
• In t...
3 copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• We assume a certain level of familiarity with Scala
syntax and ...
4 copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• If you are a seasoned Haskell programmer, you’ll find
that Scal...
5 copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• First of all let’s make it clear: There is no relationship
betw...
6 copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• The first example of a type class in Scalaz we’re going
to disc...
7 copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• Well, this looks like a simple implicit conversion that
provide...
8 copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• Consider the following code:
Discussion
8
// doesn’t compile he...
9 copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• The Order typeclass provides, well, ordering.
• E.g.:
Order
9
1...
1
0
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• Another useful Type Class is Show:
Show
10
1.show //> res0: s...
1
1
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• No more printing “com.bom.mom.X@3249234f”
because we forgot t...
1
2
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• We all favor using immutable data (and if not you
should).
• ...
1
3
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• Simple Lens usage:
Example
13
case class Customer(name: Strin...
1
4
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• Composition:
Example
14
val sampleStock1 = Stock("Sample1", 5...
1
5
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• Scenario: we need to perform validation on some data.
• We wa...
1
6
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• Validation:
Example
16
// Basic Data Types
case class Person(...
1
7
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• Ok, now let’s use the previous validation logic in a stop-
on...
1
8
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• OK, nice.
• Now lets accumulate the errors:
Accumulation
18
/...
1
9
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• First of all, you can use the following line instead of the
|...
2
0
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• We have seen here the use for ApplicativeBuilder
operator: |@...
2
1
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• And, what if we have a long sequence of validation
methods?
•...
2
2
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• Well, the Validation type is very useful compared to the
pre-...
2
3
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• Well, combinators in Validation was nice.
• Also, for-compreh...
2
4
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• The Functor type class include types that can be
mapped on.
•...
2
5
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• Applicatives were used in the validation examples.
• Let’s un...
2
6
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• We can also lift simple values into the Applicative.
• E.g.:
...
2
7
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• And there are of course, the famous Monads.
• Used in for-com...
2
8
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• Another nice type, is the Memo type that provides, well,
memo...
2
9
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• And now, with memoization:
Memo
29
def delay = {
Thread.sleep...
3
0
copyright 2013 Trainologic LTD
Scalaz – The Good Parts
• There are several memoization strategies, including:
• weakHa...
Upcoming SlideShare
Loading in …5
×

The good parts in scalaz

1,613 views

Published on

By Shimi Bandiel from Trainologic for Scalapeno Israel 2013

0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,613
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
46
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

The good parts in scalaz

  1. 1. copyright 2013 Trainologic LTD Scalaz – The Good Parts
  2. 2. 2 copyright 2013 Trainologic LTD Scalaz – The Good Parts • Scalaz is one of the famous/infamous libraries in Scala. • In this session we are going to overview some parts of it. • But first of all, who are the intended audience? Scalaz 2
  3. 3. 3 copyright 2013 Trainologic LTD Scalaz – The Good Parts • We assume a certain level of familiarity with Scala syntax and core libraries. • You should be comfort with the following declaration: Know Your Scala 3 numbers.foldRight(List.empty[Int]) {_ :: _}
  4. 4. 4 copyright 2013 Trainologic LTD Scalaz – The Good Parts • If you are a seasoned Haskell programmer, you’ll find that Scalaz resembles Haskell. • We are going to look at some features of Scalaz without discussing Category Theory. • We will see some of the power of Scalaz without going into the full definitions and laws of the concepts. • All of these have their place, but we don’t have time for it all. • Let’s start with Type Classes… Scalaz 4
  5. 5. 5 copyright 2013 Trainologic LTD Scalaz – The Good Parts • First of all let’s make it clear: There is no relationship between Type Classes and OO classes or idioms! • They arrive of course from Haskell  • A Type Class defines a set of operations that must be available on types belonging to this Type Class. • Type Classes are being used extensively in the core libraries in Scala, in 3rd parties and in Scalaz. Type-Classes 5
  6. 6. 6 copyright 2013 Trainologic LTD Scalaz – The Good Parts • The first example of a type class in Scalaz we’re going to discuss is Equal. • It provides a type safe equality check. • In contrast to the built-in Scala’s “==“ method. • E.g.: Equal 6 import scalaz._ import Scalaz._ val i1 = 5 //> i1 : Int = 5 val i2 = 6 //> i2 : Int = 6 val s1 = "8" //> s1 : String = 8 i1 == i2 //> res0: Boolean = false i1 == s1 //> res1: Boolean = false i1 === i2 //> res2: Boolean = false // i1 === s1 does not compile
  7. 7. 7 copyright 2013 Trainologic LTD Scalaz – The Good Parts • Well, this looks like a simple implicit conversion that provides the “===“ type-safe equality check. • What is the connection to Type Classes here? • Well, the way to create instances of type classes in Scala, is to use implicits. • And you can introduce your own implementations whenever you want… Discussion 7
  8. 8. 8 copyright 2013 Trainologic LTD Scalaz – The Good Parts • Consider the following code: Discussion 8 // doesn’t compile here, no implicit Equal new java.lang.Thread() === new java.lang.Thread()// implicit object eqThread extends Equal[java.lang.Thread] { def equal(a1: Thread, a2: Thread) = a1.getId === a2.getId } new java.lang.Thread() === new java.lang.Thread()//> res0: Boolean = false val t1 = new java.lang.Thread() //> t1 : Thread = Thread[Thread-2,5,main] t1 === t1 //> res1: Boolean = true
  9. 9. 9 copyright 2013 Trainologic LTD Scalaz – The Good Parts • The Order typeclass provides, well, ordering. • E.g.: Order 9 1 ?|? 2 //> res0: scalaz.Ordering = LT 1 ?|? 2.0 // does not compile
  10. 10. 1 0 copyright 2013 Trainologic LTD Scalaz – The Good Parts • Another useful Type Class is Show: Show 10 1.show //> res0: scalaz.Cord = 1 "hello".show //> res1: scalaz.Cord = "hello“ // the following line doesn’t compile here new Thread().show implicit val showThread = Show.shows[Thread] { _.getName } new Thread().show //> res2: scalaz.Cord = Thread-0
  11. 11. 1 1 copyright 2013 Trainologic LTD Scalaz – The Good Parts • No more printing “com.bom.mom.X@3249234f” because we forgot to implement toString(). • It will not compile. • You can also provide different printing for different usecases (e.g., verbose mode, admin user, etc…). Discussion 11
  12. 12. 1 2 copyright 2013 Trainologic LTD Scalaz – The Good Parts • We all favor using immutable data (and if not you should). • Especially if we’re into functional programming. • However, this means that modification results in creating a new ‘version’ of the object. • This can be quite cumbersome. • Let’s take a look at an example… Lens 12
  13. 13. 1 3 copyright 2013 Trainologic LTD Scalaz – The Good Parts • Simple Lens usage: Example 13 case class Customer(name: String, age: Int) case class Stock(name: String, price: Int) case class StockPortfolio(stocks: Map[String, Stock], customer: Customer) val john = Customer("John", 30) //> john : lens.Customer = Customer(John,30) val customerAge = Lens.lensu[Customer, Int]((a, value) ⇒ a.copy(age = value), a ⇒ a.age) val customerName = Lens.lensu[Customer, String]((a, value) ⇒ a.copy(name = value), a ⇒ a.name) val jane = customerName set (john, "Jane")//> jane : lens.Customer = Customer(Jane,30) val johnNextYear = customerAge set (john, 31) //> johnNextYear : lens.Customer = Customer(John,31) val incCustomerAge = customerAge %= {_+1} val johnNextYearAgain = incCustomerAge(john) //> johnNextYearAgain : (lens.Customer, Int) = (Customer(John,31),31)
  14. 14. 1 4 copyright 2013 Trainologic LTD Scalaz – The Good Parts • Composition: Example 14 val sampleStock1 = Stock("Sample1", 500) val sampleStock2 = Stock("Sample2", 500) val stockPrice = Lens.lensu[Stock, Int]((a, value) ⇒ a.copy(price = value), a ⇒ a.price) val portfolioCustomer = Lens.lensu[StockPortfolio, Customer]((a, value) ⇒ a.copy(customer = value), a ⇒ a.customer) val portfolioStocks = Lens.lensu[StockPortfolio, Map[String, Stock]]((a, value) ⇒ a.copy(stocks = value), a ⇒ a.stocks) val portfolio = StockPortfolio(customer = john, stocks = Map("Sample1" -> sampleStock1, "Sample2" -> sampleStock2)) portfolioStocks at "Sample1" andThen stockPrice set (portfolio, 9999) //> res0: lens.StockPortfolio = StockPortfolio(Map(Sample1 -> Stock(Sample1,9999), Sample2 -> Stock(Sample2,500)),Customer(John,30))
  15. 15. 1 5 copyright 2013 Trainologic LTD Scalaz – The Good Parts • Scenario: we need to perform validation on some data. • We want to accumulate the validations and not throw an exception and break the flow. • Scalaz provides the Validation class which can be used for this purpose. • Let’s see and discuss some examples… Validation 15
  16. 16. 1 6 copyright 2013 Trainologic LTD Scalaz – The Good Parts • Validation: Example 16 // Basic Data Types case class Person(name: String, age: Int, yearsInSchool: Int, citizenship : Boolean) // Validation Functions trait PublicInstitue { def checkEducation(p: Person): Validation[String, Person] = { if (p.yearsInSchool < 12) "Not enough education".fail else p.success } def checkCitizenship(p : Person) : Validation[String, Person] = { if (p.citizenship) p.success else "Must be a Citizen".fail } def checkAge(p : Person) : Validation[String, Person] = { if (p.age < 18) "Too young".fail else if (p.age > 65) "Too old".fail else p.success } }
  17. 17. 1 7 copyright 2013 Trainologic LTD Scalaz – The Good Parts • Ok, now let’s use the previous validation logic in a stop- on-first-failure strategy: First Usage 17 // let's try to get some persons a job at the Ministry of Wealth: object MinistryOfHealth extends PublicInstitue { def applyForJob(p : Person) : Validation[String, String] = { for { v1 <- checkEducation(p) v2 <- checkCitizenship(p) v3 <- checkAge(p) } yield s"${v1.name}, you got the job" } } // Failure(Must be a Citizen) println( MinistryOfHealth applyForJob Person("John", 30, 15, citizenship = false)) // Success(Shraga, you got the job) println( MinistryOfHealth applyForJob Person("Shraga", 30, 15, citizenship = true)) // Failure(Not enough education) println( MinistryOfHealth applyForJob Person("Dani", 13, 5, citizenship = true))
  18. 18. 1 8 copyright 2013 Trainologic LTD Scalaz – The Good Parts • OK, nice. • Now lets accumulate the errors: Accumulation 18 // let's try to get some persons a job at the Ministry of Transportation: object MinistryOfTransportation extends PublicInstitue { def applyForJob(p: Person) = { (checkEducation(p) |@| checkCitizenship(p) |@| checkAge(p)) { case (_, _, p) ⇒ s"${p.name}, you got the job" } } } println(MinistryOfTransportation applyForJob Person("John", 30, 15, citizenship = false)) println(MinistryOfTransportation applyForJob Person("Shraga", 30, 15, citizenship = true)) // Failure(Not enough educationToo young) println(MinistryOfTransportation applyForJob Person("Dani", 13, 5, citizenship = true))
  19. 19. 1 9 copyright 2013 Trainologic LTD Scalaz – The Good Parts • First of all, you can use the following line instead of the |@| operator: Discussion 19 (checkEducation(p) ⊛ checkCitizenship(p) ⊛ checkAge(p)) { • Second, concatenating strings is not that useful. • Let’s use a non empty list on the failure side: def applyForJob(p: Person) = { (checkEducation(p).toValidationNel ⊛ checkCitizenship(p).toValidationNel ⊛ checkAge(p).toValidationNel) { … } // Failure(NonEmptyList(Not enough education, Too young)) println(MinistryOfTransportation applyForJob Person("Dani", 13, 5, citizenship = true))
  20. 20. 2 0 copyright 2013 Trainologic LTD Scalaz – The Good Parts • We have seen here the use for ApplicativeBuilder operator: |@| • Also known as the “macaulay culkin” operator  ApplicativeBuilder 20
  21. 21. 2 1 copyright 2013 Trainologic LTD Scalaz – The Good Parts • And, what if we have a long sequence of validation methods? • We wouldn’t want to type all of them. Right? • We’re not going to discuss it here, but the following code will do just fine: What If? 21 def applyForJob(p: Person) = { val validations = List(checkEducation _, checkCitizenship _, checkAge _) validations.traverse[({type l[a] = ValidationNel[String, a]})#l, Person](_ andThen (_.toValidationNel) apply p) map { case p::_ ⇒ s"${p.name}, you got the job" } }
  22. 22. 2 2 copyright 2013 Trainologic LTD Scalaz – The Good Parts • Well, the Validation type is very useful compared to the pre-defined Either type. • Scalaz also provides the / type which is almost like either, but supports for-comprehensions on the right projection. Discussion 22
  23. 23. 2 3 copyright 2013 Trainologic LTD Scalaz – The Good Parts • Well, combinators in Validation was nice. • Also, for-comprehensions are nice. • Functors, Applicatives and Monads are very useful. • And they are depicted in Scalaz by appropriate Type Classes. • Let’s do a quick overview… Discussion 23
  24. 24. 2 4 copyright 2013 Trainologic LTD Scalaz – The Good Parts • The Functor type class include types that can be mapped on. • Example: Functor Type Class 24 def foo[F[_] : Functor](fs : F[Int]): F[Int] = { fs map {_ + 5} } val numbers = List(1,2,3) //> numbers : List[Int] = List(1, 2, 3) foo(numbers) //> res0: List[Int] = List(6, 7, 8) val optInt = some(5) //> optInt : Option[Int] = Some(5) foo(optInt) //> res1: Option[Int] = Some(10)
  25. 25. 2 5 copyright 2013 Trainologic LTD Scalaz – The Good Parts • Applicatives were used in the validation examples. • Let’s understand them more. • E.g.: Applicative 25 val opt1 = some(6) //> opt1 : Option[Int] = Some(6) val opt2 = some(7) //> opt2 : Option[Int] = Some(7) (opt1).<*>(opt2.map(x => (y : Int) => x + y)) //> res0: Option[Int] = Some(13) (opt1 |@| opt2) (_+_) //> res0: Option[Int] = Some(13)
  26. 26. 2 6 copyright 2013 Trainologic LTD Scalaz – The Good Parts • We can also lift simple values into the Applicative. • E.g.: Lifting into Applicative 26 (opt1 ⊛ opt2 ⊛ 6.point[Option]) (_+_ +_) //> res1: Option[Int] = Some(19)
  27. 27. 2 7 copyright 2013 Trainologic LTD Scalaz – The Good Parts • And there are of course, the famous Monads. • Used in for-comprehensions. • Instances: Option, Traversables, Validation, Reader, Writer, State, IO and many more… Monads 27
  28. 28. 2 8 copyright 2013 Trainologic LTD Scalaz – The Good Parts • Another nice type, is the Memo type that provides, well, memoization. • E.g.: Memo 28 def delay = { Thread.sleep(50) 1 } val fac: Int => Int = { case 1 => 1 case n => n*fac(n-1)*delay } val start = java.lang.System.currentTimeMillis println(fac(50)) println(fac(10)) println(fac(50)) val end = java.lang.System.currentTimeMillis println(s"${end-start} millis") // takes around 5000 millis }
  29. 29. 2 9 copyright 2013 Trainologic LTD Scalaz – The Good Parts • And now, with memoization: Memo 29 def delay = { Thread.sleep(50) 1 } val fac: Int => Int =Memo.mutableHashMapMemo { case 1 => 1 case n => n*fac(n-1)*delay } val start = java.lang.System.currentTimeMillis println(fac(50)) println(fac(10)) println(fac(50)) val end = java.lang.System.currentTimeMillis println(s"${end-start} millis") // takes around 2500 millis }
  30. 30. 3 0 copyright 2013 Trainologic LTD Scalaz – The Good Parts • There are several memoization strategies, including: • weakHashMap • Mutable/immutable maps • Arrays Memo 30

×