This is a study note of the concept of FP based on 5parts tutorial.
1 Motivation and Types
Movitivations
 Small scopes
 DI for loose coupling and easy testing
 Prviate/safe constructor
 Clean APIs
 Good domain modles
A good type system helps you
 describe the stuff: use
ADT
 describe the relationship between stuff: use restrict type in upstream
 describe the context of stuff: effects
Scala uses case class
for prodcut type and allows sealed trait
with case object
and case class
to define sum types. The mixture of sum and prodcut types is algebraic data type
(ADT
). Avoid subtyping concept in FP.
For generics, the more kinds of things something can potentially be, the less we can reason abou twhat it actually is. For example, def foo(s: String): String
is less constrained than defe foo[A](a: A): A
because you know very few about the generic version and the only function you can write is identity
.
Referential transparency enables you to change a variable with its expression and vice versa. Code can be refactored and be understood locally.
A FP application can be viewed as three nested parts:
 the outmost is the outside world
 the app boundary that has sideeffection functions that should be very strict aobut its inputs/outptus
 the core has pure functions
Pure functions are determinstic, have no side effects and are total. If also means no null, no reflection and no exceptions.
An effect is whatever distinguishes F[A]
from A
. An effect is also called a context, a program in F
, and a computation.
Pros of FP in Scala
 expressive domain model
 1st class functions
 concise generics
 ADTs and pattern matching
 typeclasses over inheritance (with macro of simplicity)
 can be referentially transparent
 reasonably type safe
 model context
Cons of FP in Scala
 different mental model
 mixed FP/OOP
 doesn’t stop you from writing bad code
 runtime DI doesn’t
2 Effects
Impure things
 partiality
 exceptions
 nondeterministism
 DI
 mutable state
 side effects
An effects is an impure thing, a box or a context. The extra things for a pure computation. It has a shape of F[A]
. Programming with effects involves
2.1 Operate on things inside of a context: Functor
 a
Functor
has amap
method, don’t care about the structure ofF
but keep the structure. def map[A, B](x: F[A](f: A => B): F[B]
def lift[A, B](f: A => B): F[A] => F[B] = fa => map(fa)(f)
. It is calledlift
because it works at a higher abstraction level.Functor
is a typeclass you can constraint a program to require
Functor
 you cannot: unwarp a functor, smoosh two functor together like
F[F[A]]
orF[A]
+F[A]
. Functor
s compose: IfF
andG
have functors, thenF[G[_]]
orG[F[_]]
is a functor.
2.2 Put thing inside of a context: Monad
A monad has the following methods
 put a thing inside a context
A => M[A]
. It is calledpure
,unit
, orpoint
.  unwrap a thing
F[F[A]] => F[A]
. It is calledflatten
orjoin
 sequence effects:
F[A] => (A => F[B]) => F[B]
. It is calledbind
,flatmap
or>>=
. The call depends on the previous value. It is used to chain together success cases and shortcircuit if something is wrong. It is a much better way than thetry/catch
.
All the monads should have the same effect type. It is used to handle success/faliure or contextal staff like reader, writer etc. In a chain of operations, each operation depends on the one before it.
2.3 Work with things nested inside of a context: Applicative
Applicative is used in a china of effectful computatoins that have no relationship with each other. The operation itself is inside a context. The method name is often called <*>
, ap
, zip
or product
. It runs multipel indepedent effects concurrently.


The application operation depends on the effect. For List
, it gets all combinations of values in each list. For Task
, it runs multiple tasks concurrently.
2.4 Inverting Containers: Traverse
To transform F[M[A]]
to M[F[A]]
, use Traverse
:


The inner class must have a type of Applicative
. If an effect has a Traverse
then it has a sequence
method to deal with nested effects.
2.5 Combine effects via unpacking and packing
Check if there is method like combineAll
, foldMap
.
2.6 Nested Monad
Use nested for
comprehension or use Monda transformers.
2.7 Abstract Over the Context: Higher Kinded Types
A F[_]
is a type constructor. You can think the *
as a hole in the type.
 Kinds describe the number of holes in a type
 The kind of an ordinary type like
Int
orChar
is*
, zero hole.  The kind of unary type constructor like
Maybe
orList
is* > *
, one hole.  The kind of binary type consructor like
Either
is* > * > *
, two holes.
3 Typeclasses
Typeclasses, better to be named type capabilities or type behaviors, are used to
 extend libs with new functionality
 allow adhoc polymorphism, no hierarchy/inheritance
 typeclasses can have an OO hierarchy
A type class is decoupled from the data type and it
 is a trait, holds no state
 has a type parameter, can be a higherkinded type parameter
 has at least one abstract method
 may contain generalized methods
 may extend other typeclasses
There should be one implementation of a typeclass for a given type in a scope, this is called typeclass coherence
. The typeclass defines a hasa
relationship for the type that implement the trait.
Typeclass suppose composition that if A
is a Monoid, you can define F[A]
in a generic way. Typeclass laws are properties that must hold for a typeclass to be valid for the type that implement it. It helps compiler to work properly.
You can use typeclasses to both describe the relationships between stuff and restrain the context. Functor
, Monad
, Applicative
are type classes on an effect that restrict the capabilities of an effect.
The differences between a typelcass and an abstract interfaces are
 A typeclass instance is decoupled from the data type.
 Typeclasses have laws.
 Typeclasses are composable by compiler.
4 Practical Effect Manipulation
Use Traverse
to invert two effects: F[G[X]]
to G[F[X]]
.


Traversable allows you to transform elements inside the structure like a functor, producing applicative effects along the way, and lift those potentially multiple instances of applicative structure outside of the traversable structure. It is commonly described as a way to traverse a data structure, mapping a function inside a structure while accumulating the applicative contexts along the way.
5 Basics of Tagless Final and ZIO
Effects are
 of type
F[A]
, representing whaever differentiatesA
fromF[A]
 stackable, such as
ReaderT[IO]
and the entire stack has a type ofF[A]
, an enviornment comprise one or more effects.
Procedure effects are sideeffecting, nondeterministic or partial interaction with the real world. A funcitonal effect is an immutable data structure that describes procedure effects. Functional effects are later interpretted in some runtime into the procedure effects they describe. A functional effect
 a context we operates in that restrict ways you can operate using DSL
 a description of procedure effects
 has referential transparency
 executed by one of many possible interpreters
There are tradeoffs in the DSL and interpreters.
The following code is used to bake a bread:


The [_]
in F[_]
denotes the idea of an effect over something. The trait defeines a generic interface of the abrstract “device” or “sevice and is called an algebra
in FP.
The model is defined as the following:


The error is defined as algebraic data type (ADT):


The actual ovens are instances of the Oven
type, are called interpreters. the algebra doesn’t assume anything about that other than defin a set of actions on an interpreter instance. A version could be:


The F[_]: Sync
chooses the type of effect, also called boundaries
or capabilities
. It means that the effect type needs to be an instance of a Sync
typeclass. In cats, it is the capability of suspending the execution of sideeffecting code. Here it can delay
, raise
error and point
a function.
To run the code, we need to choose a concrete instance of the sync
type class to be the runtime. The followinmg use the IO
type.


The runtime can be changed to ZIO, as the following:


The tagless final has four steps:
 define algebra
 define domain model
 define interpreter
 choose a ruttime and an effect type