functional scala

29
Functional Scala The Math Connection: From Functions to Free Monads https://github.com/ReactivePatterns/functional-scala

Upload: stan-lea

Post on 15-Feb-2017

73 views

Category:

Software


1 download

TRANSCRIPT

Page 1: Functional Scala

Functional ScalaThe Math Connection: From Functions to Free Monads

https://github.com/ReactivePatterns/functional-scala

Page 2: Functional Scala

Functional IngredientsThe Math Connection

• Functions

• Higher Order Functions (chaining with map, reduce, etc.)

• For-Comprehensions

• Monads (chainable computation steps)

• Algebraic Data Types (functional APIs)

• Free Monads (interpreters)

Page 3: Functional Scala

Basic Scala Concepts• 3 fundamental building blocks: expressions, values, types

• Valid expressions have a type and calculate a value

• Literals are the simplest expressions

• Blocks are compound expressions built with operators and flow control expressions (e.g. conditionals)

• Expressions can be pure or can have side-effects

• Every value is an object

• Reusability support: value declarations, functions, methods

• Programs are built from the building blocks (abstractions and reusability are not required and often avoided)

Page 4: Functional Scala

Basic Functional IngredientsScala Math

Functionf: A => B

A and B are types

f: A → B

A and B are sets

HOFList[A] method:

map[B](f: A => B): List[A]

{f(a) | a ∈ A}

Generalizes to objects in categories

SequenceComprehension

for (i <- List.range(0, 20) if i % 2 == 0) yield i

List(0, 2, 4, 6, 8, 10, 12, 14, 16, 18){i | i ∈ ℕ, 0 ≤ i < 20, i ≡ 0 (mod 2)}

ForComprehension

for { i <- 0 until 20; j <- i until 20 if i + j == 32 } yield Pair(i, j);

(13, 19) (14, 18) (15, 17) (16, 16)

{(i, j) | i, j ∈ ℕ, 0 ≤ i, j < 20, i + j = 32}

Page 5: Functional Scala

Sequential Computation1. What comes next?

• 1, 3, 5, 7, ?

• 0, 1, 1, 2, 3, 5, ?

2. Steps can be ordered linearly or as a (directed acyclic) graph

3. Steps can be: expressions, functions, abstractions

4. Each step represents or produces a value

Page 6: Functional Scala

Example: Alexa Volume API

level

Volume

level: Int

Volume[Int]

level: Double

Volume[Double]

f

flatMap(f)

Page 7: Functional Scala

Unit, FlatMap, Map and For-Comprehensions

level: Int

Volume[Int]

level: Double

Volume[Double]

f

map(f)

level

Volume

level

Volume

f

flatMap(unit(f))

unit(f)

unit

Page 8: Functional Scala

Flatten

level: A

Volume[A]

level: A

Volume[A]

f

flatMap(f)

Volume[Volume[A]]

map(f)flatten

Page 9: Functional Scala

Compose

level: A

Volume[A]

level: B

Volume[B]

f

flatMap(f)

level: C

Volume[C]

g

flatMap(g)

Page 10: Functional Scala

MonadsThree elements:

1. Type constructor F[_] that takes one argument (e.g. List, Function0, Option, Either, Future)

2. A monadic unit, a function that takes a value of any type A and produces a value of type F[A]

3. A monadic composition operation that takes a function of type A => F[B], and a function of type B => F[C] and produces a function of type A => F[C]

Two laws:

1. Identity: compose(unit, f) = f = compose(f, unit)

2. Associativity: compose(compose(f, g), h) = compose(f, compose(g, h))

Page 11: Functional Scala

Example: Statistical Distributions

sample

Distribution

Page 12: Functional Scala

Dice Throwing As a Computation

Page 13: Functional Scala

The Monty Hall Problemto switch or

not to switch?

Page 14: Functional Scala

Monty Hall Problem As a Computation

vs

Page 15: Functional Scala

Functional Derivation of Distributions

Page 16: Functional Scala

Existing Monad Implementations

• Cats

• Scalaz

• Akka Agents

• Observable

• Unfortunately NOT Akka Streams

Page 17: Functional Scala

API Functional Design• Behavior + Types = Algebra

• Return abstractions (monadic types like Try, Either, Future, Observable, etc.)

Page 18: Functional Scala

Railway Oriented ProgrammingDesigning For Failure

Page 19: Functional Scala

Implementation• Functions are lifted to monadic steps (could do that automatically, a topic for another talk)

• State can be managed in a functional manner too (a topic for another talk)

Page 20: Functional Scala

For-Comprehensions or Direct FlatMaps Allow Step Sequencing/Composition

Page 21: Functional Scala

Future Based VersionAkka Agents are used to manage state

Page 22: Functional Scala

HTTP Endpoint

Page 23: Functional Scala

Contracts as Union TypesADT = Algebraic Data Type

Page 24: Functional Scala

Free Monads as Interpreters• represent stateful computations as data, and run them

• run recursive computations in a stack-safe way

• build an embedded DSL (domain-specific language)

• retarget a computation to another interpreter using natural transformations

https://github.com/typelevel/cats/blob/master/docs/src/main/tut/freemonad.md

Page 25: Functional Scala

Free APIWrite a sequence of instructions in the embedded DSL as a "program", compile the "program", and finally execute the "program" to interact with the actual key-value store.

Page 26: Functional Scala

Interpreters/CompilersDependency Injection done right

Page 27: Functional Scala

Logic is Passed to InterpretersStructure, interpretation and execution are separate concerns

Page 28: Functional Scala

Advanced Topic: Lifting Functions Two Instructions Are Enough

Page 29: Functional Scala

Summary and Conclusions

• Abstractions give an unfair advantage

• Map and FlatMap are sometimes enough

• Composition through For-Comprehensions is readily available

• Standardizing computation steps pays big

• Functions are enough as building blocks (they can be lifted to objects, actors, etc.)