SlideShare a Scribd company logo
1 of 57
© Mesan AS
scalaz
En nybegynners introduksjon
© Mesan AS
Agenda
• Bakgrunnen for at jeg har tatt i bruk
scalaz
• En vei gjennom rammeverket
• Konklusjoner
• Gjerne spørsmål underveis!
© Mesan AS
Trond Marius Øvstetun
• Sjesfkonsulent i
Mesan
• Utvikler, arkitekt,
teamleder +++
© Mesan AS
Mesan
... når standardsystemer ikke er nok
•Systemutvikling – skreddersøm
•Løsningsfokus
•Transaksjonssystemer
•Lang levetid – langsiktighet og
vedlikeholdbarhet
© Mesan AS
Hvorfor scalaz?
© Mesan AS
Hvorfor scalaz?
• If you are thinking about using Scalaz,
stop now while you still have your
sanity! ref
• Don’t listen to anyone telling you to use
Scalaz!
• Hva er greia med metodene
<:::, :::>, <+>, |@|, , , <=< ?★ ☆
© Mesan AS
Mitt triggerpunkt
© Mesan AS
unfiltered og json
case req @ POST(Path("/person")) => {
val x = Body.string(req)
val p: Person = read[Person](x)
val id: Int = personer.add(p)
Created ~> Json("id" -> id)
}
case class Person(name: String, age: Int)
© Mesan AS
json
val json = """{"name": "Petter", "age": 22}"""
read[Person](json)
val json = """{"name":"Petter"}"""
read[Person](json)
=> Person(Petter, 22)
=> org.json4s.package$MappingException:
No usable value for age
Did not find value which can be converted
into int
© Mesan AS
Validering av input
def add(p: Person): Int = {
Validate.isTrue(p.age > 18 && p.age < 60)
1
}
case req @ POST(Path("/person")) => {
val x = Body.string(req)
val p: Person = read[Person](x)
val id: Int = personer.add(p)
Created ~> Json("id" -> id)
}
© Mesan AS
Fra en klients
perspektiv...
© Mesan AS
Fra en utviklers
perspektiv
Dette føles ikke bra!
© Mesan AS
validering med scalaz
case req @ POST(Path("/personz")) => {
val x = Body.string(req)
val p = fromJSON[Person](parse(x))
val id = p map personer.add
id match {
case Success(i) => Created ~> Json("id"->i)
case Failure(errors) =>
Forbidden ~>
Json("errors" ->
jsonErrors(errors).toList)
}
}
© Mesan AS
validering med scalaz
case req @ POST(Path("/personz")) => {
val x = Body.string(req)
val p = fromJSON[Person](parse(x))
val id = p map personer.add
id match {
case Success(i) => Created ~> Json("id"->i)
case Failure(errors) =>
Forbidden ~>
Json("errors" ->
jsonErrors(errors).toList)
}
}
implicit val personR: JSONR[Person] =
Person.applyJSON(field[String]("name"),
validate[Int]("age") >==>
min(18) >==> max(60))
© Mesan AS
Fra en klients
perspektiv...
© Mesan AS
Fra en utviklers
perspektiv
Mye bedre?! Men?!
>==> fromJSON[Person]
Kleisli[Result, JValue, A]
type EitherNel[+a] = NonEmptyList[Error] / a
© Mesan AS
scalaz
import scalaz._
import Scalaz._
© Mesan AS
Hva er scalaz?
• 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.
© Mesan AS
Hva er scalaz?
1.Funksjonelle datastrukturer
2.Syntaks for utvidelse av standard
klasser
3.Typeklasser og instanser for disse
© Mesan AS
Syntaks
utvidelser til standard klasser
og til hvordan du skriver kode
© Mesan AS
Equal
1 == 1
=> true
1 == 1.0
=> true
val x: Int = 1
val y: Person = new Person("Petter")
x == y
warning: comparing values of types Int and Person
using `==' will always yield false
=> false
y == x
warning: Person and Int are unrelated:
they will most likely never compare equal
=> false
1 == 1
=> false
© Mesan AS
Typesikker Equal
1 === 1
=> true
1 === 1.0
error: could not find implicit
value for parameter F0: scalaz.Equal[Any]
1 =/= 1
=> false
1 =/= 1.0
error: could not find implicit
value for parameter F0: scalaz.Equal[Any]
1 === 2
=> false
1 =/= 2
=> true
© Mesan AS
Boolean
true && true
=> true
true / true
=> true
true && false
=> false
true / false
=> false
(if (true) "a" else "b")
=> "a"
true ? "a" | "b"
=> "a"
true option "a"
=> Some("a")
false option "a"
=> (None:Option[String])
© Mesan AS
Option
Some(42)
=> Some[Int] = Some(42)
None
=> None.type = None
some(42)
=> Option[Int] = Some(42)
none[Int]
=> Option[Int] = None
42.some
=> Some(42)
val o = 42.some
o getOrElse 1
o | 1
=> 42
val n = option.none[Int]
n getOrElse 1
n | 1
=> 1
~o
=> 42
~n
=> 0
© Mesan AS
Index
val l = List(1,2,3,4)
l(0)
=> 1
l(2)
=> 3
l(-1)
=> IndexOutOfBoundsException
l(4)
=> IndexOutOfBoundsException
l index 0
=> Some(1)
l index 2
=> Some(3)
l index -1
=> None
l index 4
=> None
© Mesan AS
Alle instanser - Id
"a" ?? "b"
=> "a"
val x: String = null
x ?? "asdf"
=> "asdf"
def f(i:Int) = i + 1
(1 |> f)
=> 2
1 + 2 + 3 |> {_ * 6}
=> 36
© Mesan AS
Typeklasser
© Mesan AS
Hva er en Typeklasse?
• En form for et interface som definerer
oppførsel til en type
• oppførselen er definert utenfor typen
• alle typer som er medlem i typeklassen
har implementasjoner av oppførselen
• ikke et interface som i Java
© Mesan AS
Typeklasser i Scala
trait Truthy[A] {
def truthy(a: A): Boolean
}
implicit val intTruthy: Truthy[Int] = new Truthy[Int] {
def truthy(a: Int): Boolean = a match {
case 0 => false
case _ => true
}
}
intTruthy.truthy(1)
=> true
intTruthy.truthy(0)
=> false
© Mesan AS
Typeklasser i Scala
object Truthy {
def apply[A](implicit A: Truthy[A]): Truthy[A] = A
}
> Truthy[Int].truthy(0)
=> false
Truthy[Int].truthy(1)
=> true
1.truthy
=> true
© Mesan AS
Typeklasser i Scala
trait TruthyOps[A] {
def self: A
implicit def F:Truthy[A]
def truthy: Boolean = F.truthy(self)
}
object ToTruthyOps {
implicit def toTOps[A](a: A)(implicit ev: Truthy[A]) =
new TruthyOps[A] {
def self: A = a
implicit def F = ev
}
}
1.truthy
=> true
© Mesan AS
Typeklasser i Scala
def iffy[A: Truthy, B](t: A)(ifT: =>B)(ifF: =>B): B = {
if (t.truthy) ifT else ifF
}
iffy(1)("Ja!")("Neeei!")
=> Ja!
iffy(0)("Ja!")("Neeei!")
=> Neeei!
© Mesan AS
Typeklasser i Scalaz
© Mesan AS
Typeklasser i Scalaz
© Mesan AS
Equal
trait Equal[F] { self =>
def equal(a1: F, a2: F): Boolean
}
implicit val intInstance: Monoid[Int] with Enum[Int] with Show[Int] =
new Monoid[Int] with Enum[Int] with Show[Int] {
....
}
trait EqualOps[F] extends Ops[F] {
final def ===(other: F): Boolean = ???
final def =/=(other: F): Boolean = ???
}
1 === 1
=> true
© Mesan AS
Equal
case class Car(val model: String)
implicit val carEqual = new Equal[Car] {
def equal(a1: Car, a2: Car): Boolean =
a1.model == a2.model
}
Car("Honda") === Car("Toyota")
=> false
Car("Honda") === Car("Honda")
=> true
© Mesan AS
SemiGroup
trait Semigroup[F] { self =>
def append(f1: F, f2: => F): F
}
trait SemigroupOps[F] extends Ops[F] {
implicit def F: Semigroup[F]
final def |+|(other: => F): F = ???
final def mappend(other: => F): F = ???
}
1 |+| 2
=> 3
List(1,2) |+| List(3,4)
=> List(1,2,3,4)
(1,2) |+| (3,4)
=> (4,6)
© Mesan AS
Monoid
trait Monoid[F] extends Semigroup[F] { self =>
def zero: F
}
trait MonoidOps[F] extends Ops[F] {
final def multiply(n: Int): F = ???
final def ifEmpty[A](tv: => A)(fv: => A) = ???
}
(0.ifEmpty("Empty")("NonEmpty"))
=> "Empty"
(1.ifEmpty("Empty")("NonEmpty"))
=> "NonEmpty"
"a" multiply 3
=> "aaa"
~o.none[Int]
=> 0
~3.some
=> 3
© Mesan AS
Monoid avler Monoid!
• Option[A] er Monoid hvis A er Monoid
• Map[K, A] er Monoid hivs A er Monoid
• (A, B) er Monoid hvis A og B er Monoid!
(1,2) |+| (3,4)
=> (4,6)
Map(1->1, 2->3) |+| Map(1->4, 3->6)
=> Map(1->5, 2->3, 3->6)
(1.some, 2.some) |+| (3.some, o.none[Int])
=> (4.some, 2.some)
© Mesan AS
Og Monider er overalt..
• Tall (Int, Double, BigDecimal....)
• Penger (Din egen klasse)
• Dato / Perioder
• Kun fantasien setter grenser...
100.NOK |+| 250.NOK
=> Money(350, NOK)
1.day |+| 1.week
=> Period(1, 1)
© Mesan AS
Functor
trait Functor[F[_]] { self =>
def map[A, B](fa: F[A])(f: A => B): F[B]
}
List(1, 2, 3) map {_ + 1}
=> List(2,3,4)
trait FunctorOps[F[_],A] extends Ops[F[A]] {
final def map[B](f: A => B): F[B] = ???
final def fpair: F[(A, A)] = ???
final def fproduct[B](f: A => B): F[(A, B)] = ???
final def >|[B](b: => B): F[B] = ???
}
List(1,2,3) >| "a"
=> List("a","a","a")
(List(1,2,3) fpair)
=> List((1,1),(2,2),(3,3))
List(1,2,3) fproduct {_*2}
=> List((1,2), (2,4), (3,6))
© Mesan AS
Applicative
trait Applicative[F[_]] extends Apply[F] { self =>
def point[A](a: => A): F[A]
}
trait Apply[F[_]] extends Functor[F] { self =>
def ap[A,B](fa: => F[A])(f: => F[A => B]): F[B]
}
trait ApplyOps[F[_],A] extends Ops[F[A]] {
final def <*>[B](f: F[A => B]): F[B] = ???
final def |@|[B](fb: F[B]):ApplicativeBuilder= ???
}
© Mesan AS
Applicative
val f = (_:Int) * 3
2.some <*> f.some
=> 6.some
9.some <*> { (_: Int) + 3 }.some
=> 12.some
^(1.some, 2.some) {_ + _}
=> 3.some
(1.some |@| 2.some) {_ + _}
=> 3.some
© Mesan AS
Applicative
val f: (Int, Int) => Int = (x:Int, y:Int) => x + y
f(1,2)
=> 3
f(1.some, 2.some)
=> 3.some
f(1.some, o.none[Int])
=> o.none[Int]
© Mesan AS
Monad
trait BindOps[F[_],A] extends Ops[F[A]] {
def flatMap[B](f: A => F[B]) = ???
def >>=[B](f: A => F[B]) = ???
def >>[B](b: => F[B]): F[B] = ???
}
val f: Int => Option[Int] = (x:Int) => (x * 10).some
(9.some >>= f)
(9.some flatMap f)
(for {
x <- 9.some
y <- f(x)
} yield y)
=> 90.some
(9.some >> 4.some)
=> 4.some
© Mesan AS
Validation
endelig
© Mesan AS
Validation
sealed trait Validation[+E, +A]
case class Success[E, A](a: A)
extends Validation[E, A]
case class Failure[E, A](e: E)
extends Validation[E, A]
type ValidationNel[+E, +X] =
Validation[NonEmptyList[E], X]
© Mesan AS
Validation
1.success[String]
=> scalaz.Validation[String,Int] = Success(1)
1.successNel[String]
=> scalaz.ValidationNel[String,Int] = Success(1)
1.successNel
=> scalaz.ValidationNel[Nothing,Int] = Success(1)
© Mesan AS
Validation
"Too young!".failNel[Int]
=> Failure(NonEmptyList("Too young!"))
"Too young!".fail[Int]
=> Failure("Too young!")
"Too young!".fail
=> Failure("Too young!")
© Mesan AS
Validation
case class User(username:String)
def addUser(username: String): ValidationNel[String, User] = {
findUser(username) match {
case Some(_) => s"Username '${username}' taken!".failNel
case _ => User(username).success
}
}
def findUser(username: String): Option[User] = {
(username === "ovstetun") ? User("ovstetun").some | none
}
addUser("per")
=> Success(User("per"))
addUser("ovstetun")
=> Failure(NonEmptyList("Username 'ovstetun' taken!"))
© Mesan AS
Validation
val e: Equal[Validation[String, Int]] =
Equal[Validation[String, Int]]
val sg: Semigroup[Validation[String, Int]] =
Semigroup[Validation[String, Int]]
val m: Monoid[Validation[String, Int]] =
Monoid[Validation[String, Int]]
val a: Applicative[({type l[a] = Validation[String, a]})#l] =
Validation.ValidationApplicative[String]
val t: Traverse[({type l[a] = Validation[String, a]})#l] =
Traverse[({type l[a] = Validation[String, a]})#l]
© Mesan AS
Validation
case req @ POST(Path("/personz")) => {
val x = Body.string(req)
val p = fromJSON[Person](parse(x))
val id = p map personer.add
id match {
case Success(i) => Created ~> Json("id"->i)
case Failure(errors) =>
Forbidden ~>
Json("errors" ->
jsonErrors(errors).toList)
}
}
def add(p: Person): Int = ???
© Mesan AS
Konklusjoner
© Mesan AS
Konklusjoner
• Scalaz er ikke farlig
• Gir en felles måte å løse like problemer
• Man trenger ikke skjønne hvordan et
konsept er implementert for å bruke det
• Validation er killer feature for meg
• Gjenbrukbar, komponerbar og
vedlikeholdbar kode
© Mesan AS
Referanser
• Scalaz på github
• http://eed3si9n.com/learning-scalaz/
© Mesan AS
Q & A
© Mesan AS
Takk for meg!
tmo@mesan.no
@ovstetun
github.com/ovstetun/beginner-scalaz

More Related Content

What's hot

Send + More = Money – Let’s mash 2 monads to solve a simple CSP
Send + More = Money – Let’s mash 2 monads to solve a simple CSPSend + More = Money – Let’s mash 2 monads to solve a simple CSP
Send + More = Money – Let’s mash 2 monads to solve a simple CSPFilippo Vitale
 
Stanfy MadCode Meetup #9: Functional Programming 101 with Swift
Stanfy MadCode Meetup #9: Functional Programming 101 with SwiftStanfy MadCode Meetup #9: Functional Programming 101 with Swift
Stanfy MadCode Meetup #9: Functional Programming 101 with SwiftStanfy
 
Aggregate Functions,Final
Aggregate Functions,FinalAggregate Functions,Final
Aggregate Functions,Finalmukesh24pandey
 
Aggregate functions
Aggregate functionsAggregate functions
Aggregate functionssinhacp
 
The Ring programming language version 1.9 book - Part 31 of 210
The Ring programming language version 1.9 book - Part 31 of 210The Ring programming language version 1.9 book - Part 31 of 210
The Ring programming language version 1.9 book - Part 31 of 210Mahmoud Samir Fayed
 
The Ring programming language version 1.5.3 book - Part 24 of 184
The Ring programming language version 1.5.3 book - Part 24 of 184The Ring programming language version 1.5.3 book - Part 24 of 184
The Ring programming language version 1.5.3 book - Part 24 of 184Mahmoud Samir Fayed
 
An example of R code for Data visualization
An example of R code for Data visualizationAn example of R code for Data visualization
An example of R code for Data visualizationLiang (Leon) Zhou
 
The Ring programming language version 1.2 book - Part 14 of 84
The Ring programming language version 1.2 book - Part 14 of 84The Ring programming language version 1.2 book - Part 14 of 84
The Ring programming language version 1.2 book - Part 14 of 84Mahmoud Samir Fayed
 

What's hot (14)

Send + More = Money – Let’s mash 2 monads to solve a simple CSP
Send + More = Money – Let’s mash 2 monads to solve a simple CSPSend + More = Money – Let’s mash 2 monads to solve a simple CSP
Send + More = Money – Let’s mash 2 monads to solve a simple CSP
 
Swift Study #2
Swift Study #2Swift Study #2
Swift Study #2
 
Stanfy MadCode Meetup #9: Functional Programming 101 with Swift
Stanfy MadCode Meetup #9: Functional Programming 101 with SwiftStanfy MadCode Meetup #9: Functional Programming 101 with Swift
Stanfy MadCode Meetup #9: Functional Programming 101 with Swift
 
Aggregate Functions,Final
Aggregate Functions,FinalAggregate Functions,Final
Aggregate Functions,Final
 
Aggregate functions
Aggregate functionsAggregate functions
Aggregate functions
 
Functional programming in scala
Functional programming in scalaFunctional programming in scala
Functional programming in scala
 
The Ring programming language version 1.9 book - Part 31 of 210
The Ring programming language version 1.9 book - Part 31 of 210The Ring programming language version 1.9 book - Part 31 of 210
The Ring programming language version 1.9 book - Part 31 of 210
 
Fp java8
Fp java8Fp java8
Fp java8
 
Scala for Jedi
Scala for JediScala for Jedi
Scala for Jedi
 
The Ring programming language version 1.5.3 book - Part 24 of 184
The Ring programming language version 1.5.3 book - Part 24 of 184The Ring programming language version 1.5.3 book - Part 24 of 184
The Ring programming language version 1.5.3 book - Part 24 of 184
 
A bit about Scala
A bit about ScalaA bit about Scala
A bit about Scala
 
R for you
R for youR for you
R for you
 
An example of R code for Data visualization
An example of R code for Data visualizationAn example of R code for Data visualization
An example of R code for Data visualization
 
The Ring programming language version 1.2 book - Part 14 of 84
The Ring programming language version 1.2 book - Part 14 of 84The Ring programming language version 1.2 book - Part 14 of 84
The Ring programming language version 1.2 book - Part 14 of 84
 

Viewers also liked

Gdg using docker to streamline development
Gdg using docker to streamline developmentGdg using docker to streamline development
Gdg using docker to streamline developmentTrond Marius Øvstetun
 
Юрий Буянов «Squeryl — ORM с человеческим лицом»
Юрий Буянов «Squeryl — ORM с человеческим лицом»Юрий Буянов «Squeryl — ORM с человеческим лицом»
Юрий Буянов «Squeryl — ORM с человеческим лицом»e-Legion
 
Sea Snake (Lapemis hardwickii)
Sea Snake (Lapemis hardwickii)Sea Snake (Lapemis hardwickii)
Sea Snake (Lapemis hardwickii)kaiser AS
 
Whats In The Box
Whats In The BoxWhats In The Box
Whats In The Boxninja321
 
Global Warming Save Earth
Global Warming Save EarthGlobal Warming Save Earth
Global Warming Save Earthtomjose
 
Bioremediation Of Heavy Metals (Copper)
Bioremediation Of Heavy Metals (Copper)Bioremediation Of Heavy Metals (Copper)
Bioremediation Of Heavy Metals (Copper)kaiser AS
 
Robot PowerPoint
Robot PowerPointRobot PowerPoint
Robot PowerPointbradschultz
 
Bollywood retail
Bollywood retailBollywood retail
Bollywood retailAmber Ahmed
 

Viewers also liked (20)

Gdg using docker to streamline development
Gdg using docker to streamline developmentGdg using docker to streamline development
Gdg using docker to streamline development
 
Юрий Буянов «Squeryl — ORM с человеческим лицом»
Юрий Буянов «Squeryl — ORM с человеческим лицом»Юрий Буянов «Squeryl — ORM с человеческим лицом»
Юрий Буянов «Squeryl — ORM с человеческим лицом»
 
Sugar Asia2009 Summary
Sugar Asia2009 SummarySugar Asia2009 Summary
Sugar Asia2009 Summary
 
Sea Snake (Lapemis hardwickii)
Sea Snake (Lapemis hardwickii)Sea Snake (Lapemis hardwickii)
Sea Snake (Lapemis hardwickii)
 
Web 2
Web 2Web 2
Web 2
 
Whats In The Box
Whats In The BoxWhats In The Box
Whats In The Box
 
Leadership Quotes V5
Leadership Quotes V5Leadership Quotes V5
Leadership Quotes V5
 
Media
MediaMedia
Media
 
Global Warming Save Earth
Global Warming Save EarthGlobal Warming Save Earth
Global Warming Save Earth
 
Jellyfish
JellyfishJellyfish
Jellyfish
 
Cnidaria:Jellyfish
Cnidaria:JellyfishCnidaria:Jellyfish
Cnidaria:Jellyfish
 
Black Merchant 1
Black Merchant 1Black Merchant 1
Black Merchant 1
 
Game on
Game onGame on
Game on
 
ScalaQuery
ScalaQueryScalaQuery
ScalaQuery
 
Bioremediation Of Heavy Metals (Copper)
Bioremediation Of Heavy Metals (Copper)Bioremediation Of Heavy Metals (Copper)
Bioremediation Of Heavy Metals (Copper)
 
Persistens i scala
Persistens i scalaPersistens i scala
Persistens i scala
 
Robot PowerPoint
Robot PowerPointRobot PowerPoint
Robot PowerPoint
 
Midi Chlorians
Midi ChloriansMidi Chlorians
Midi Chlorians
 
Personalitarkvara Persona
Personalitarkvara PersonaPersonalitarkvara Persona
Personalitarkvara Persona
 
Bollywood retail
Bollywood retailBollywood retail
Bollywood retail
 

Similar to Scalaz for Beginners Introduction

関数潮流(Function Tendency)
関数潮流(Function Tendency)関数潮流(Function Tendency)
関数潮流(Function Tendency)riue
 
Christian Gill ''Functional programming for the people''
Christian Gill ''Functional programming for the people''Christian Gill ''Functional programming for the people''
Christian Gill ''Functional programming for the people''OdessaJS Conf
 
Functional programming in ruby
Functional programming in rubyFunctional programming in ruby
Functional programming in rubyKoen Handekyn
 
ES6 and AngularAMD
ES6 and AngularAMDES6 and AngularAMD
ES6 and AngularAMDdhaval10690
 
Operators and expressions in c language
Operators and expressions in c languageOperators and expressions in c language
Operators and expressions in c languagetanmaymodi4
 
Operators inc c language
Operators inc c languageOperators inc c language
Operators inc c languageTanmay Modi
 
Advance Scala - Oleg Mürk
Advance Scala - Oleg MürkAdvance Scala - Oleg Mürk
Advance Scala - Oleg MürkPlanet OS
 
Grokking Monads in Scala
Grokking Monads in ScalaGrokking Monads in Scala
Grokking Monads in ScalaTim Dalton
 
358 33 powerpoint-slides_5-arrays_chapter-5
358 33 powerpoint-slides_5-arrays_chapter-5358 33 powerpoint-slides_5-arrays_chapter-5
358 33 powerpoint-slides_5-arrays_chapter-5sumitbardhan
 
Monadologie
MonadologieMonadologie
Monadologieleague
 
Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)Sumant Tambe
 
Introduction to R programming
Introduction to R programmingIntroduction to R programming
Introduction to R programmingAlberto Labarga
 
CBSE XII COMPUTER SCIENCE STUDY MATERIAL BY KVS
CBSE XII COMPUTER SCIENCE STUDY MATERIAL BY KVSCBSE XII COMPUTER SCIENCE STUDY MATERIAL BY KVS
CBSE XII COMPUTER SCIENCE STUDY MATERIAL BY KVSGautham Rajesh
 

Similar to Scalaz for Beginners Introduction (20)

R Programming Intro
R Programming IntroR Programming Intro
R Programming Intro
 
関数潮流(Function Tendency)
関数潮流(Function Tendency)関数潮流(Function Tendency)
関数潮流(Function Tendency)
 
Christian Gill ''Functional programming for the people''
Christian Gill ''Functional programming for the people''Christian Gill ''Functional programming for the people''
Christian Gill ''Functional programming for the people''
 
Functional programming in ruby
Functional programming in rubyFunctional programming in ruby
Functional programming in ruby
 
ES6 and AngularAMD
ES6 and AngularAMDES6 and AngularAMD
ES6 and AngularAMD
 
20100528
2010052820100528
20100528
 
20100528
2010052820100528
20100528
 
Operators and expressions in c language
Operators and expressions in c languageOperators and expressions in c language
Operators and expressions in c language
 
Operators inc c language
Operators inc c languageOperators inc c language
Operators inc c language
 
Advance Scala - Oleg Mürk
Advance Scala - Oleg MürkAdvance Scala - Oleg Mürk
Advance Scala - Oleg Mürk
 
Practical cats
Practical catsPractical cats
Practical cats
 
Programming in R
Programming in RProgramming in R
Programming in R
 
Grokking Monads in Scala
Grokking Monads in ScalaGrokking Monads in Scala
Grokking Monads in Scala
 
358 33 powerpoint-slides_5-arrays_chapter-5
358 33 powerpoint-slides_5-arrays_chapter-5358 33 powerpoint-slides_5-arrays_chapter-5
358 33 powerpoint-slides_5-arrays_chapter-5
 
Begin with Python
Begin with PythonBegin with Python
Begin with Python
 
Scala by Luc Duponcheel
Scala by Luc DuponcheelScala by Luc Duponcheel
Scala by Luc Duponcheel
 
Monadologie
MonadologieMonadologie
Monadologie
 
Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)
 
Introduction to R programming
Introduction to R programmingIntroduction to R programming
Introduction to R programming
 
CBSE XII COMPUTER SCIENCE STUDY MATERIAL BY KVS
CBSE XII COMPUTER SCIENCE STUDY MATERIAL BY KVSCBSE XII COMPUTER SCIENCE STUDY MATERIAL BY KVS
CBSE XII COMPUTER SCIENCE STUDY MATERIAL BY KVS
 

Recently uploaded

AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 

Recently uploaded (20)

AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 

Scalaz for Beginners Introduction

  • 1. © Mesan AS scalaz En nybegynners introduksjon
  • 2. © Mesan AS Agenda • Bakgrunnen for at jeg har tatt i bruk scalaz • En vei gjennom rammeverket • Konklusjoner • Gjerne spørsmål underveis!
  • 3. © Mesan AS Trond Marius Øvstetun • Sjesfkonsulent i Mesan • Utvikler, arkitekt, teamleder +++
  • 4. © Mesan AS Mesan ... når standardsystemer ikke er nok •Systemutvikling – skreddersøm •Løsningsfokus •Transaksjonssystemer •Lang levetid – langsiktighet og vedlikeholdbarhet
  • 6. © Mesan AS Hvorfor scalaz? • If you are thinking about using Scalaz, stop now while you still have your sanity! ref • Don’t listen to anyone telling you to use Scalaz! • Hva er greia med metodene <:::, :::>, <+>, |@|, , , <=< ?★ ☆
  • 7. © Mesan AS Mitt triggerpunkt
  • 8. © Mesan AS unfiltered og json case req @ POST(Path("/person")) => { val x = Body.string(req) val p: Person = read[Person](x) val id: Int = personer.add(p) Created ~> Json("id" -> id) } case class Person(name: String, age: Int)
  • 9. © Mesan AS json val json = """{"name": "Petter", "age": 22}""" read[Person](json) val json = """{"name":"Petter"}""" read[Person](json) => Person(Petter, 22) => org.json4s.package$MappingException: No usable value for age Did not find value which can be converted into int
  • 10. © Mesan AS Validering av input def add(p: Person): Int = { Validate.isTrue(p.age > 18 && p.age < 60) 1 } case req @ POST(Path("/person")) => { val x = Body.string(req) val p: Person = read[Person](x) val id: Int = personer.add(p) Created ~> Json("id" -> id) }
  • 11. © Mesan AS Fra en klients perspektiv...
  • 12. © Mesan AS Fra en utviklers perspektiv Dette føles ikke bra!
  • 13. © Mesan AS validering med scalaz case req @ POST(Path("/personz")) => { val x = Body.string(req) val p = fromJSON[Person](parse(x)) val id = p map personer.add id match { case Success(i) => Created ~> Json("id"->i) case Failure(errors) => Forbidden ~> Json("errors" -> jsonErrors(errors).toList) } }
  • 14. © Mesan AS validering med scalaz case req @ POST(Path("/personz")) => { val x = Body.string(req) val p = fromJSON[Person](parse(x)) val id = p map personer.add id match { case Success(i) => Created ~> Json("id"->i) case Failure(errors) => Forbidden ~> Json("errors" -> jsonErrors(errors).toList) } } implicit val personR: JSONR[Person] = Person.applyJSON(field[String]("name"), validate[Int]("age") >==> min(18) >==> max(60))
  • 15. © Mesan AS Fra en klients perspektiv...
  • 16. © Mesan AS Fra en utviklers perspektiv Mye bedre?! Men?! >==> fromJSON[Person] Kleisli[Result, JValue, A] type EitherNel[+a] = NonEmptyList[Error] / a
  • 17. © Mesan AS scalaz import scalaz._ import Scalaz._
  • 18. © Mesan AS Hva er scalaz? • 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.
  • 19. © Mesan AS Hva er scalaz? 1.Funksjonelle datastrukturer 2.Syntaks for utvidelse av standard klasser 3.Typeklasser og instanser for disse
  • 20. © Mesan AS Syntaks utvidelser til standard klasser og til hvordan du skriver kode
  • 21. © Mesan AS Equal 1 == 1 => true 1 == 1.0 => true val x: Int = 1 val y: Person = new Person("Petter") x == y warning: comparing values of types Int and Person using `==' will always yield false => false y == x warning: Person and Int are unrelated: they will most likely never compare equal => false 1 == 1 => false
  • 22. © Mesan AS Typesikker Equal 1 === 1 => true 1 === 1.0 error: could not find implicit value for parameter F0: scalaz.Equal[Any] 1 =/= 1 => false 1 =/= 1.0 error: could not find implicit value for parameter F0: scalaz.Equal[Any] 1 === 2 => false 1 =/= 2 => true
  • 23. © Mesan AS Boolean true && true => true true / true => true true && false => false true / false => false (if (true) "a" else "b") => "a" true ? "a" | "b" => "a" true option "a" => Some("a") false option "a" => (None:Option[String])
  • 24. © Mesan AS Option Some(42) => Some[Int] = Some(42) None => None.type = None some(42) => Option[Int] = Some(42) none[Int] => Option[Int] = None 42.some => Some(42) val o = 42.some o getOrElse 1 o | 1 => 42 val n = option.none[Int] n getOrElse 1 n | 1 => 1 ~o => 42 ~n => 0
  • 25. © Mesan AS Index val l = List(1,2,3,4) l(0) => 1 l(2) => 3 l(-1) => IndexOutOfBoundsException l(4) => IndexOutOfBoundsException l index 0 => Some(1) l index 2 => Some(3) l index -1 => None l index 4 => None
  • 26. © Mesan AS Alle instanser - Id "a" ?? "b" => "a" val x: String = null x ?? "asdf" => "asdf" def f(i:Int) = i + 1 (1 |> f) => 2 1 + 2 + 3 |> {_ * 6} => 36
  • 28. © Mesan AS Hva er en Typeklasse? • En form for et interface som definerer oppførsel til en type • oppførselen er definert utenfor typen • alle typer som er medlem i typeklassen har implementasjoner av oppførselen • ikke et interface som i Java
  • 29. © Mesan AS Typeklasser i Scala trait Truthy[A] { def truthy(a: A): Boolean } implicit val intTruthy: Truthy[Int] = new Truthy[Int] { def truthy(a: Int): Boolean = a match { case 0 => false case _ => true } } intTruthy.truthy(1) => true intTruthy.truthy(0) => false
  • 30. © Mesan AS Typeklasser i Scala object Truthy { def apply[A](implicit A: Truthy[A]): Truthy[A] = A } > Truthy[Int].truthy(0) => false Truthy[Int].truthy(1) => true 1.truthy => true
  • 31. © Mesan AS Typeklasser i Scala trait TruthyOps[A] { def self: A implicit def F:Truthy[A] def truthy: Boolean = F.truthy(self) } object ToTruthyOps { implicit def toTOps[A](a: A)(implicit ev: Truthy[A]) = new TruthyOps[A] { def self: A = a implicit def F = ev } } 1.truthy => true
  • 32. © Mesan AS Typeklasser i Scala def iffy[A: Truthy, B](t: A)(ifT: =>B)(ifF: =>B): B = { if (t.truthy) ifT else ifF } iffy(1)("Ja!")("Neeei!") => Ja! iffy(0)("Ja!")("Neeei!") => Neeei!
  • 35. © Mesan AS Equal trait Equal[F] { self => def equal(a1: F, a2: F): Boolean } implicit val intInstance: Monoid[Int] with Enum[Int] with Show[Int] = new Monoid[Int] with Enum[Int] with Show[Int] { .... } trait EqualOps[F] extends Ops[F] { final def ===(other: F): Boolean = ??? final def =/=(other: F): Boolean = ??? } 1 === 1 => true
  • 36. © Mesan AS Equal case class Car(val model: String) implicit val carEqual = new Equal[Car] { def equal(a1: Car, a2: Car): Boolean = a1.model == a2.model } Car("Honda") === Car("Toyota") => false Car("Honda") === Car("Honda") => true
  • 37. © Mesan AS SemiGroup trait Semigroup[F] { self => def append(f1: F, f2: => F): F } trait SemigroupOps[F] extends Ops[F] { implicit def F: Semigroup[F] final def |+|(other: => F): F = ??? final def mappend(other: => F): F = ??? } 1 |+| 2 => 3 List(1,2) |+| List(3,4) => List(1,2,3,4) (1,2) |+| (3,4) => (4,6)
  • 38. © Mesan AS Monoid trait Monoid[F] extends Semigroup[F] { self => def zero: F } trait MonoidOps[F] extends Ops[F] { final def multiply(n: Int): F = ??? final def ifEmpty[A](tv: => A)(fv: => A) = ??? } (0.ifEmpty("Empty")("NonEmpty")) => "Empty" (1.ifEmpty("Empty")("NonEmpty")) => "NonEmpty" "a" multiply 3 => "aaa" ~o.none[Int] => 0 ~3.some => 3
  • 39. © Mesan AS Monoid avler Monoid! • Option[A] er Monoid hvis A er Monoid • Map[K, A] er Monoid hivs A er Monoid • (A, B) er Monoid hvis A og B er Monoid! (1,2) |+| (3,4) => (4,6) Map(1->1, 2->3) |+| Map(1->4, 3->6) => Map(1->5, 2->3, 3->6) (1.some, 2.some) |+| (3.some, o.none[Int]) => (4.some, 2.some)
  • 40. © Mesan AS Og Monider er overalt.. • Tall (Int, Double, BigDecimal....) • Penger (Din egen klasse) • Dato / Perioder • Kun fantasien setter grenser... 100.NOK |+| 250.NOK => Money(350, NOK) 1.day |+| 1.week => Period(1, 1)
  • 41. © Mesan AS Functor trait Functor[F[_]] { self => def map[A, B](fa: F[A])(f: A => B): F[B] } List(1, 2, 3) map {_ + 1} => List(2,3,4) trait FunctorOps[F[_],A] extends Ops[F[A]] { final def map[B](f: A => B): F[B] = ??? final def fpair: F[(A, A)] = ??? final def fproduct[B](f: A => B): F[(A, B)] = ??? final def >|[B](b: => B): F[B] = ??? } List(1,2,3) >| "a" => List("a","a","a") (List(1,2,3) fpair) => List((1,1),(2,2),(3,3)) List(1,2,3) fproduct {_*2} => List((1,2), (2,4), (3,6))
  • 42. © Mesan AS Applicative trait Applicative[F[_]] extends Apply[F] { self => def point[A](a: => A): F[A] } trait Apply[F[_]] extends Functor[F] { self => def ap[A,B](fa: => F[A])(f: => F[A => B]): F[B] } trait ApplyOps[F[_],A] extends Ops[F[A]] { final def <*>[B](f: F[A => B]): F[B] = ??? final def |@|[B](fb: F[B]):ApplicativeBuilder= ??? }
  • 43. © Mesan AS Applicative val f = (_:Int) * 3 2.some <*> f.some => 6.some 9.some <*> { (_: Int) + 3 }.some => 12.some ^(1.some, 2.some) {_ + _} => 3.some (1.some |@| 2.some) {_ + _} => 3.some
  • 44. © Mesan AS Applicative val f: (Int, Int) => Int = (x:Int, y:Int) => x + y f(1,2) => 3 f(1.some, 2.some) => 3.some f(1.some, o.none[Int]) => o.none[Int]
  • 45. © Mesan AS Monad trait BindOps[F[_],A] extends Ops[F[A]] { def flatMap[B](f: A => F[B]) = ??? def >>=[B](f: A => F[B]) = ??? def >>[B](b: => F[B]): F[B] = ??? } val f: Int => Option[Int] = (x:Int) => (x * 10).some (9.some >>= f) (9.some flatMap f) (for { x <- 9.some y <- f(x) } yield y) => 90.some (9.some >> 4.some) => 4.some
  • 47. © Mesan AS Validation sealed trait Validation[+E, +A] case class Success[E, A](a: A) extends Validation[E, A] case class Failure[E, A](e: E) extends Validation[E, A] type ValidationNel[+E, +X] = Validation[NonEmptyList[E], X]
  • 48. © Mesan AS Validation 1.success[String] => scalaz.Validation[String,Int] = Success(1) 1.successNel[String] => scalaz.ValidationNel[String,Int] = Success(1) 1.successNel => scalaz.ValidationNel[Nothing,Int] = Success(1)
  • 49. © Mesan AS Validation "Too young!".failNel[Int] => Failure(NonEmptyList("Too young!")) "Too young!".fail[Int] => Failure("Too young!") "Too young!".fail => Failure("Too young!")
  • 50. © Mesan AS Validation case class User(username:String) def addUser(username: String): ValidationNel[String, User] = { findUser(username) match { case Some(_) => s"Username '${username}' taken!".failNel case _ => User(username).success } } def findUser(username: String): Option[User] = { (username === "ovstetun") ? User("ovstetun").some | none } addUser("per") => Success(User("per")) addUser("ovstetun") => Failure(NonEmptyList("Username 'ovstetun' taken!"))
  • 51. © Mesan AS Validation val e: Equal[Validation[String, Int]] = Equal[Validation[String, Int]] val sg: Semigroup[Validation[String, Int]] = Semigroup[Validation[String, Int]] val m: Monoid[Validation[String, Int]] = Monoid[Validation[String, Int]] val a: Applicative[({type l[a] = Validation[String, a]})#l] = Validation.ValidationApplicative[String] val t: Traverse[({type l[a] = Validation[String, a]})#l] = Traverse[({type l[a] = Validation[String, a]})#l]
  • 52. © Mesan AS Validation case req @ POST(Path("/personz")) => { val x = Body.string(req) val p = fromJSON[Person](parse(x)) val id = p map personer.add id match { case Success(i) => Created ~> Json("id"->i) case Failure(errors) => Forbidden ~> Json("errors" -> jsonErrors(errors).toList) } } def add(p: Person): Int = ???
  • 54. © Mesan AS Konklusjoner • Scalaz er ikke farlig • Gir en felles måte å løse like problemer • Man trenger ikke skjønne hvordan et konsept er implementert for å bruke det • Validation er killer feature for meg • Gjenbrukbar, komponerbar og vedlikeholdbar kode
  • 55. © Mesan AS Referanser • Scalaz på github • http://eed3si9n.com/learning-scalaz/
  • 57. © Mesan AS Takk for meg! tmo@mesan.no @ovstetun github.com/ovstetun/beginner-scalaz

Editor's Notes

  1. én av MANGE mulig veier gjennom rammeverket
  2. 13 års erfaring som java-utvikler -&gt; konsulent siden 2005 Java, Scala, HTML/js
  3. har mange ganger tenkt at “eg må se på scalaz” for det er kult -&gt; men liksom aldri kommet i gang
  4. Mye er endret i versjon 7. lite unicode-metodenavn strukturen er bedre og mer lagvis
  5. Hva pushet meg over kanten? Laget en applikasjon med Unfiltered som et json-api Ikke et godt REST-api, så ingen kommentarer om det ;)
  6. med json4s (eller lift-json) denne koden har (minst) ett problem - en ting vi ikke kontrollerer...
  7. “ Spring+commons-lang måten” -&gt; kaster IllegalArgumentException hvis brutt..
  8. live demo i Postman!
  9. Mange grunner til det... -&gt; usynlige effekter i kode -&gt; mangel på kontroll -&gt; Runtime-exceptions
  10. Uten å gå inn på HVORDAN (for det kommer vi tilbake til) så -&gt; Peke på det mest interessante som skjer her! Result[A] -&gt; enten Success MED objekt i -&gt; eller Failure med feilmeldinger
  11. Er eksplisitt på hvordan en entitet hentes ut fra json Valideringsregler legges på
  12. live demo i Postman med scalaz og jsonscalaz!
  13. MEN noe er magisk Signaturer med navn som Kleisli[EitherNel, A, V] type EitherNel[+a] hva ER dette?
  14. Fra github. Dette sa ikke meg så mye...
  15. Hvordan EG ser på scalaz IkkeTomListe (NonEmptyList) Trær \/ (høyrevridd Either) Memo -&gt; Memoization av funksjoner
  16. Typesikker equals!
  17. Typesikker equals!
  18. conjunction (AND) disjunction (OR) ternary option-syntaks
  19. ?? -&gt; omtrent som en “getOrElse” a |&gt; f -&gt; som en f(a) kan syntaktisk skrive i motsatt rekkefølge av normalt -&gt; tenk “putt inn i funksjon”
  20. Gjøre et eksempel som “javascript-aktig-truthy-ting” Implementeres som et trait Dette er måten det er implementert i scalaz, kan gjøres litt annerledes om man vil...
  21. ønsker at 1.truthy =&gt; true
  22. figur, skal si hva noen av disse gjør!
  23. Skal si noe om disse...
  24. Vi snakket om denne tidligere. Scalaz deler Typeklassen (som kan brukes direkte) Syntaksen den tilbyr i Ops-klassen Også en implisitt konvertering som legger på Ops
  25. Representerer det å “logisk legge sammen to objekter” (å legge til i |+|-tilfellet) Ops[F] definerer bare “self: F” som en variabel i en wrappet klasse
  26. husk tilbake til Option: ~-operator som gir Monoid[A].zero som resultat dersom tom!
  27. Dette gjelder kanskje MEST for SemiGroup-delen, men det meste som er Monoid er også SG! Og det nøstes -&gt; Tuppel av Option[A] er monoid hvis A er Monoid
  28. Konsistent måte å legge ting sammen på - uansett hva det er
  29. alt som kan mappes over... “ kjør funksjon på en verdi i en kontekst, og putt verdien inn i kontekst igjen”
  30. Som functor -&gt; men med en applikativ er også funksjonen i en kontekst!
  31. AUTOMATISK lifting av funksjoner til applikative functorer der det trengs!
  32. En Monad er noe man kan kalle flatMap på =&gt; altså kan brukes i for-comprehensions &gt;&gt;= er alias for flatMap -&gt; fra Haskell &gt;&gt; er en shortcut som bytter ut
  33. Hvordan vi lager Success-instanser. Merk at vi kan enten angi hvilken type, eller droppe det (og la det være en del av signaturen)
  34. Hvordan vi lager Failure-instanser. Merk at vi kan enten angi hvilken type, eller droppe det (og la det være en del av signaturen)
  35. Hvordan et API kan se ut med Validation
  36. Det finnes typeklasseinstanser for Validation De fleste “låser” den ene typen Men det lar oss gjøre det vi gjorde i innledningen:
  37. Mine konklusjoner rundt Scalaz -&gt; dette gjelder for meg -&gt; men alle bør gjøre opp sin egen mening i motsetning til det mange mener -&gt; scalaz er ikke farlig Felles løsning -&gt; selv om det ikke alltid er enkelt å se at problemet er det samme...
  38. OG ta gjerne tak i meg på Mesan-standen i expo-området!