Function Programming in Scala.
A lot of my examples here comes from the book
Functional programming in Scala By Paul Chiusano and Rúnar Bjarnason, It is a good book, buy it.
This presentation takes you on a functional programming journey, it starts from basic Scala programming language design concepts and leads to a concept of Monads, how some of them designed in Scala and what is the purpose of them
This presentation takes you on a functional programming journey, it starts from basic Scala programming language design concepts and leads to a concept of Monads, how some of them designed in Scala and what is the purpose of them
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Philip Schwarz
Quicksort - a whistle-stop tour of the algorithm in five languages and four paradigms.
Programming Paradigms: Functional, Logic, Imperative, Imperative Functional
Languages: Haskell, Scala, Java, Clojure, Prolog
download for better quality - Learn about the sequence and traverse functions through the work of Runar Bjarnason and Paul Chiusano, authors of Functional Programming in Scala https://www.manning.com/books/functional-programming-in-scala, and Sam Halliday, author of "Functional Programming for Mortals with Scalaz" https://leanpub.com/fpmortals
In this chapter we are going to get familiar with some of the basic presentations of data in programming: lists and linear data structures. Very often in order to solve a given problem we need to work with a sequence of elements. For example, to read completely this book we have to read sequentially each page, i.e. to traverse sequentially each of the elements of the set of the pages in the book. Depending on the task, we have to apply different operations on this set of data. In this chapter we will introduce the concept of abstract data types (ADT) and will explain how a certain ADT can have multiple different implementations. After that we shall explore how and when to use lists and their implementations (linked list, doubly-linked list and array-list). We are going to see how for a given task one structure may be more convenient than another. We are going to consider the structures "stack" and "queue", as well as their applications. We are going to get familiar with some implementations of these structures.
In this chapter we will learn about arrays as a way to work with sequences of elements of the same type. We will explain what arrays are, how we declare, create, instantiate and use them. We will examine one-dimensional and multidimensional arrays. We will learn different ways to iterate through the array, read from the standard input and write to the standard output. We will give many example exercises, which can be solved using arrays and we will show how useful they really are.
In this presentation, You will get to know about Function Literal,Higher Order Function,Partial Function,Partial Applied Function,Nested Function,Closures.
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...Philip Schwarz
Learn how to write FP code that displays a graphical representation of all the numerous N-Queens solutions for N=4,5,6,7,8 .
See how to neatly solve the problem by exploiting its self-similarity and using a divide and conquer approach.
Make light work of assembling multiple images into a whole, by exploiting Doodle’s facilities for combining images using a relative layout.
See relevant FP functions, like Foldable’s intercalate and intersperse, in action.
Code for part 3: https://github.com/philipschwarz/n-queens-combinatorial-problem-scala-part-3
Functional Core and Imperative Shell - Game of Life Example - Haskell and ScalaPhilip Schwarz
See a program structure flowchart used to highlight how an FP program breaks down into a functional core and imperative shell
View a program structure flowchart for the Game of Life
See the code for Game of Life’s functional core and imperative shell, both in Haskell and in Scala.
Code:
https://github.com/philipschwarz/functional-core-imperative-shell-scala
https://github.com/philipschwarz/functional-core-imperative-shell-haskell
Download for better quality.
Functor Composition - including (starting from) the definition in Bartosz Milewski's Category Theory book. https://github.com/hmemcpy/milewski-ctfp-pdf
Download for flawless quality (slides viewed online look a bit grainy and out of focus). A monad is an implementation of one of the minimal sets of monadic combinators, satisfying the laws of associativity and identity - see how compositional responsibilities are distributed in each combinator set
Function Programming in Scala.
A lot of my examples here comes from the book
Functional programming in Scala By Paul Chiusano and Rúnar Bjarnason, It is a good book, buy it.
Functional programming in Scala. Looking at various examples of defining a program first and executing it at some later stage, separating pure functions from side effects.
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Philip Schwarz
Quicksort - a whistle-stop tour of the algorithm in five languages and four paradigms.
Programming Paradigms: Functional, Logic, Imperative, Imperative Functional
Languages: Haskell, Scala, Java, Clojure, Prolog
download for better quality - Learn about the sequence and traverse functions through the work of Runar Bjarnason and Paul Chiusano, authors of Functional Programming in Scala https://www.manning.com/books/functional-programming-in-scala, and Sam Halliday, author of "Functional Programming for Mortals with Scalaz" https://leanpub.com/fpmortals
In this chapter we are going to get familiar with some of the basic presentations of data in programming: lists and linear data structures. Very often in order to solve a given problem we need to work with a sequence of elements. For example, to read completely this book we have to read sequentially each page, i.e. to traverse sequentially each of the elements of the set of the pages in the book. Depending on the task, we have to apply different operations on this set of data. In this chapter we will introduce the concept of abstract data types (ADT) and will explain how a certain ADT can have multiple different implementations. After that we shall explore how and when to use lists and their implementations (linked list, doubly-linked list and array-list). We are going to see how for a given task one structure may be more convenient than another. We are going to consider the structures "stack" and "queue", as well as their applications. We are going to get familiar with some implementations of these structures.
In this chapter we will learn about arrays as a way to work with sequences of elements of the same type. We will explain what arrays are, how we declare, create, instantiate and use them. We will examine one-dimensional and multidimensional arrays. We will learn different ways to iterate through the array, read from the standard input and write to the standard output. We will give many example exercises, which can be solved using arrays and we will show how useful they really are.
In this presentation, You will get to know about Function Literal,Higher Order Function,Partial Function,Partial Applied Function,Nested Function,Closures.
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...Philip Schwarz
Learn how to write FP code that displays a graphical representation of all the numerous N-Queens solutions for N=4,5,6,7,8 .
See how to neatly solve the problem by exploiting its self-similarity and using a divide and conquer approach.
Make light work of assembling multiple images into a whole, by exploiting Doodle’s facilities for combining images using a relative layout.
See relevant FP functions, like Foldable’s intercalate and intersperse, in action.
Code for part 3: https://github.com/philipschwarz/n-queens-combinatorial-problem-scala-part-3
Functional Core and Imperative Shell - Game of Life Example - Haskell and ScalaPhilip Schwarz
See a program structure flowchart used to highlight how an FP program breaks down into a functional core and imperative shell
View a program structure flowchart for the Game of Life
See the code for Game of Life’s functional core and imperative shell, both in Haskell and in Scala.
Code:
https://github.com/philipschwarz/functional-core-imperative-shell-scala
https://github.com/philipschwarz/functional-core-imperative-shell-haskell
Download for better quality.
Functor Composition - including (starting from) the definition in Bartosz Milewski's Category Theory book. https://github.com/hmemcpy/milewski-ctfp-pdf
Download for flawless quality (slides viewed online look a bit grainy and out of focus). A monad is an implementation of one of the minimal sets of monadic combinators, satisfying the laws of associativity and identity - see how compositional responsibilities are distributed in each combinator set
Function Programming in Scala.
A lot of my examples here comes from the book
Functional programming in Scala By Paul Chiusano and Rúnar Bjarnason, It is a good book, buy it.
Functional programming in Scala. Looking at various examples of defining a program first and executing it at some later stage, separating pure functions from side effects.
Generic Functional Programming with Type ClassesTapio Rautonen
What it takes to build type assisted domain specific languages in Scala? Introducing the concepts of type classes, functional programming and generic algebra.
Principles of functional progrmming in scalaehsoon
a short outline on necessity of functional programming and principles of functional programming in Scala.
In the article some keyword are used but not explained (to keep the article short and simple), the interested reader can look them up in internet.
Developing Distributed High-performance Computing Capabilities of an Open Sci...Globus
COVID-19 had an unprecedented impact on scientific collaboration. The pandemic and its broad response from the scientific community has forged new relationships among public health practitioners, mathematical modelers, and scientific computing specialists, while revealing critical gaps in exploiting advanced computing systems to support urgent decision making. Informed by our team’s work in applying high-performance computing in support of public health decision makers during the COVID-19 pandemic, we present how Globus technologies are enabling the development of an open science platform for robust epidemic analysis, with the goal of collaborative, secure, distributed, on-demand, and fast time-to-solution analyses to support public health.
Cyaniclab : Software Development Agency Portfolio.pdfCyanic lab
CyanicLab, an offshore custom software development company based in Sweden,India, Finland, is your go-to partner for startup development and innovative web design solutions. Our expert team specializes in crafting cutting-edge software tailored to meet the unique needs of startups and established enterprises alike. From conceptualization to execution, we offer comprehensive services including web and mobile app development, UI/UX design, and ongoing software maintenance. Ready to elevate your business? Contact CyanicLab today and let us propel your vision to success with our top-notch IT solutions.
In software engineering, the right architecture is essential for robust, scalable platforms. Wix has undergone a pivotal shift from event sourcing to a CRUD-based model for its microservices. This talk will chart the course of this pivotal journey.
Event sourcing, which records state changes as immutable events, provided robust auditing and "time travel" debugging for Wix Stores' microservices. Despite its benefits, the complexity it introduced in state management slowed development. Wix responded by adopting a simpler, unified CRUD model. This talk will explore the challenges of event sourcing and the advantages of Wix's new "CRUD on steroids" approach, which streamlines API integration and domain event management while preserving data integrity and system resilience.
Participants will gain valuable insights into Wix's strategies for ensuring atomicity in database updates and event production, as well as caching, materialization, and performance optimization techniques within a distributed system.
Join us to discover how Wix has mastered the art of balancing simplicity and extensibility, and learn how the re-adoption of the modest CRUD has turbocharged their development velocity, resilience, and scalability in a high-growth environment.
Into the Box Keynote Day 2: Unveiling amazing updates and announcements for modern CFML developers! Get ready for exciting releases and updates on Ortus tools and products. Stay tuned for cutting-edge innovations designed to boost your productivity.
First Steps with Globus Compute Multi-User EndpointsGlobus
In this presentation we will share our experiences around getting started with the Globus Compute multi-user endpoint. Working with the Pharmacology group at the University of Auckland, we have previously written an application using Globus Compute that can offload computationally expensive steps in the researcher's workflows, which they wish to manage from their familiar Windows environments, onto the NeSI (New Zealand eScience Infrastructure) cluster. Some of the challenges we have encountered were that each researcher had to set up and manage their own single-user globus compute endpoint and that the workloads had varying resource requirements (CPUs, memory and wall time) between different runs. We hope that the multi-user endpoint will help to address these challenges and share an update on our progress here.
Code reviews are vital for ensuring good code quality. They serve as one of our last lines of defense against bugs and subpar code reaching production.
Yet, they often turn into annoying tasks riddled with frustration, hostility, unclear feedback and lack of standards. How can we improve this crucial process?
In this session we will cover:
- The Art of Effective Code Reviews
- Streamlining the Review Process
- Elevating Reviews with Automated Tools
By the end of this presentation, you'll have the knowledge on how to organize and improve your code review proces
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamtakuyayamamoto1800
In this slide, we show the simulation example and the way to compile this solver.
In this solver, the Helmholtz equation can be solved by helmholtzFoam. Also, the Helmholtz equation with uniformly dispersed bubbles can be simulated by helmholtzBubbleFoam.
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...informapgpstrackings
Keep tabs on your field staff effortlessly with Informap Technology Centre LLC. Real-time tracking, task assignment, and smart features for efficient management. Request a live demo today!
For more details, visit us : https://informapuae.com/field-staff-tracking/
How Recreation Management Software Can Streamline Your Operations.pptxwottaspaceseo
Recreation management software streamlines operations by automating key tasks such as scheduling, registration, and payment processing, reducing manual workload and errors. It provides centralized management of facilities, classes, and events, ensuring efficient resource allocation and facility usage. The software offers user-friendly online portals for easy access to bookings and program information, enhancing customer experience. Real-time reporting and data analytics deliver insights into attendance and preferences, aiding in strategic decision-making. Additionally, effective communication tools keep participants and staff informed with timely updates. Overall, recreation management software enhances efficiency, improves service delivery, and boosts customer satisfaction.
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Shahin Sheidaei
Games are powerful teaching tools, fostering hands-on engagement and fun. But they require careful consideration to succeed. Join me to explore factors in running and selecting games, ensuring they serve as effective teaching tools. Learn to maintain focus on learning objectives while playing, and how to measure the ROI of gaming in education. Discover strategies for pitching gaming to leadership. This session offers insights, tips, and examples for coaches, team leads, and enterprise leaders seeking to teach from simple to complex concepts.
Quarkus Hidden and Forbidden ExtensionsMax Andersen
Quarkus has a vast extension ecosystem and is known for its subsonic and subatomic feature set. Some of these features are not as well known, and some extensions are less talked about, but that does not make them less interesting - quite the opposite.
Come join this talk to see some tips and tricks for using Quarkus and some of the lesser known features, extensions and development techniques.
Listen to the keynote address and hear about the latest developments from Rachana Ananthakrishnan and Ian Foster who review the updates to the Globus Platform and Service, and the relevance of Globus to the scientific community as an automation platform to accelerate scientific discovery.
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Mind IT Systems
Healthcare providers often struggle with the complexities of chronic conditions and remote patient monitoring, as each patient requires personalized care and ongoing monitoring. Off-the-shelf solutions may not meet these diverse needs, leading to inefficiencies and gaps in care. It’s here, custom healthcare software offers a tailored solution, ensuring improved care and effectiveness.
Enhancing Research Orchestration Capabilities at ORNL.pdfGlobus
Cross-facility research orchestration comes with ever-changing constraints regarding the availability and suitability of various compute and data resources. In short, a flexible data and processing fabric is needed to enable the dynamic redirection of data and compute tasks throughout the lifecycle of an experiment. In this talk, we illustrate how we easily leveraged Globus services to instrument the ACE research testbed at the Oak Ridge Leadership Computing Facility with flexible data and task orchestration capabilities.
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Globus
The U.S. Geological Survey (USGS) has made substantial investments in meeting evolving scientific, technical, and policy driven demands on storing, managing, and delivering data. As these demands continue to grow in complexity and scale, the USGS must continue to explore innovative solutions to improve its management, curation, sharing, delivering, and preservation approaches for large-scale research data. Supporting these needs, the USGS has partnered with the University of Chicago-Globus to research and develop advanced repository components and workflows leveraging its current investment in Globus. The primary outcome of this partnership includes the development of a prototype enterprise repository, driven by USGS Data Release requirements, through exploration and implementation of the entire suite of the Globus platform offerings, including Globus Flow, Globus Auth, Globus Transfer, and Globus Search. This presentation will provide insights into this research partnership, introduce the unique requirements and challenges being addressed and provide relevant project progress.
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns
Unlocking Business Potential: Tailored Technology Solutions by Prosigns
Discover how Prosigns, a leading technology solutions provider, partners with businesses to drive innovation and success. Our presentation showcases our comprehensive range of services, including custom software development, web and mobile app development, AI & ML solutions, blockchain integration, DevOps services, and Microsoft Dynamics 365 support.
Custom Software Development: Prosigns specializes in creating bespoke software solutions that cater to your unique business needs. Our team of experts works closely with you to understand your requirements and deliver tailor-made software that enhances efficiency and drives growth.
Web and Mobile App Development: From responsive websites to intuitive mobile applications, Prosigns develops cutting-edge solutions that engage users and deliver seamless experiences across devices.
AI & ML Solutions: Harnessing the power of Artificial Intelligence and Machine Learning, Prosigns provides smart solutions that automate processes, provide valuable insights, and drive informed decision-making.
Blockchain Integration: Prosigns offers comprehensive blockchain solutions, including development, integration, and consulting services, enabling businesses to leverage blockchain technology for enhanced security, transparency, and efficiency.
DevOps Services: Prosigns' DevOps services streamline development and operations processes, ensuring faster and more reliable software delivery through automation and continuous integration.
Microsoft Dynamics 365 Support: Prosigns provides comprehensive support and maintenance services for Microsoft Dynamics 365, ensuring your system is always up-to-date, secure, and running smoothly.
Learn how our collaborative approach and dedication to excellence help businesses achieve their goals and stay ahead in today's digital landscape. From concept to deployment, Prosigns is your trusted partner for transforming ideas into reality and unlocking the full potential of your business.
Join us on a journey of innovation and growth. Let's partner for success with Prosigns.
Prosigns: Transforming Business with Tailored Technology Solutions
Fp in scala part 2
1. FP in Scala
the exploratorium for monads (part 2)
2. for comprehension (review)
Use the OO/FP hybrid style List code
we can do
def test = {
val a = List(1,2)
val b = List(3,4)
for {
t1 <- a
t2 <- b
} yield ((t1,t2))
}
We get
[ (1,3) (1,4) (2,3) (2,4) ]
3. for comprehension (review)
It is in fact flatMap/map in disguise, it is same as
def test = {
val a = List(1,2)
val b = List(3,4)
a.flatMap {
t1 => b.map {
t2 => (t1,t2)
}
}
}
Types that has flatMap implemented is a Monadic type (You can use flatMap
to implement map)
4. Error Handling
This can cause ArithmeticException
def mean(xs: Seq[Double]): Double =
xs.sum / xs.length
Explicitly throw it, this is not pure (does not always return)
def mean(xs: Seq[Double]): Double =
if (xs.isEmpty)
throw new ArithmeticException("mean of empty list!")
else xs.sum / xs.length
Have default number instead of throw exception,this is pure as it return Double
all the time. But still bad for using a Double to represent empty List
def mean_1(xs: IndexedSeq[Double], onEmpty: Double): Double =
if (xs.isEmpty) onEmpty
else xs.sum / xs.length
All What else can we do?
5. Option/Try/Either
sealed trait Option[+A]
case object None extends Option[Nothing]
case class Some[+A](get: A) extends Option[A]
def mean_option(xs: Seq[Double]): Option[Double] =
if (xs.isEmpty) None
else Some(xs.sum / xs.length)
sealed trait Try[+T]
case class Failure[+T](exception: Throwable) extends Try[T]
case class Success[+T](value: T) extends Try[T]
def mean_try(xs: Seq[Double]): Try[Double] =
if (xs.isEmpty) Failure(new ArithmeticException("mean of
empty list!"))
else Success(xs.sum / xs.length)
sealed trait Either[+E,+A]
case class Left[+E](get: E) extends Either[E,Nothing]
case class Right[+A](get: A) extends Either[Nothing,A]
def mean_either(xs: Seq[Double]): Either[String, Double] =
if (xs.isEmpty) Left("Why gave me a empty Seq and ask me to
get mean?")
else Right(xs.sum / xs.length)
Now we return a richer type that can represent
correct value and a wrong value, Option represent
wrong value as None (Nothing), Try represent with
wrong value as Failure (Throwable), Either
represent wrong value as some type you specified.
6. Option/Try/Either
They all are monadic types, and have flatMap,
map and filter defined with them (Either is not a
monad, but left/right projection of Either are), so
we can use the for comprehension.
The error (the part that we do not want) will
propagate in the chain of operations. One error
means final result is error.
def test = for {
x <- mean_option(Seq(1,2,3,4,5))
y <- mean_option(Seq(4,5))
z <- mean_option(Seq())
} yield (x+y+z)
None
def test = for {
x <- mean_either(Seq(1,2,3,4,5)).left
y <- mean_either(Seq(4,5)).left
z <- mean_either(Seq()).left
} yield (x+y+z)
Right(3.0)
def test = for {
x <- mean_either(Seq(1,2,3,4,5)).right
y <- mean_either(Seq(4,5)).right
z <- mean_either(Seq()).right
} yield (x+y+z)
Left(Why gave me a empty Seq and ask me
to get mean?)
def test1 = for {
x <- mean_try(Seq(1,2,3,4,5))
y <- mean_try(Seq(4,5))
z <- mean_try(Seq())
} yield (x+y+z)
Failure(java.lang.
ArithmeticException: mean of empty
list!)
7. Option/Try/Either
Option, Try and Either all have much more
combinators (functions that work on the them)
give them even more tools to be useful
You can see it in the links above.
8. Laziness / Strictness
Generally speaking, laziness lets us separate
the description of an expression from the
evaluation of that expression.
Strictness is just link the description of an
expression and the evaluation of that
expression together.
9. Stream
We want to do this:
List(1,2,3,4).map(_ + 10).filter(_ % 2 == 0).map(_ * 3)
It is in fact:
List(1,2,3,4).map(_ + 10).filter(_ % 2 == 0).map(_ * 3)
List(11,12,13,14).filter(_ % 2 == 0).map(_ * 3)
List(12,14).map(_ * 3)
List(36,42)
3 passes
We can in fact use Laziness make it one pass
10. Examine Laziness
false && { println("!!"); true }
true || { println("!!"); false }
if (input.isEmpty) sys.error("empty input") else input
These are in fact all lazy evaluation (no prints)
We can do the same:
def if2[A](cond: Boolean, onTrue: => A, onFalse: => A): A =
if (cond) onTrue else onFalse
=> A here means lazy evaluate the passed in parameter,
by not evaluating them until they are used.
if2(false, sys.error("fail"), 3)
get 3
11. Examine Laziness
def maybeTwice(b: Boolean, i: => Int) = if (b) i+i else 0
val x = maybeTwice(true, { println("hi"); 1+41 })
get
hi
hi
84
the above is because lazy Param evaluated every time,we can fix it by using
this:
def maybeTwice2(b: Boolean, i: => Int) = {
lazy val j = i
if (b) j+j else 0
}
val x = maybeTwice2(true, { println("hi"); 1+41 })
get
hi
84
Because lazy val will cache the value
12. Stream (Lazy List)
sealed abstract class Stream[+A]
object Empty extends Stream[Nothing]
sealed abstract class Cons[+A] extends Stream[A]
def empty[A]: Stream[A] = Empty // A "smart constructor" for creating an empty stream of a particular type.
def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = new Cons[A] { // A "smart constructor" for creating a nonempty stream.
lazy val head = hd // The head and tail are implemented by lazy vals.
lazy val tail = tl
}
By carefully using lazy val and => in parameter list, we can
achieve the lazy List: Stream, whose data member will not
be evaluated before get used.
14. Stream
def unfold[A, S](z: S)(f: S => Option[(A, S)]): Stream[A] =
f(z) match {
case Some((h,s)) => cons(h, unfold(s)(f))
case None => empty
}
unfold is a generic powerful
combinator to generate infinite
Stream.
val fibsViaUnfold: Stream[Int] = cons(0,
unfold((0,1)) { case (f0,f1) => Some((f1,(f1,f0+f1))) })
def test6 = fibsViaUnfold.take(5).toList
get
List(0, 1, 1, 2, 3)
Stream is also a monadic type like
List, and can use for comprehension:
def test = {
val a = Stream(1,2)
val b = Stream(3,4)
for {
t1 <- a
t2 <- b
} yield ((t1,t2))
}
get
Stream((1,3), ?)
? means it is lazy evaluated, you need
to use toList/foreach to get the real
value
15. Future
trait Future[+T]
when complete return a Try[T]
trait Promise[T]
It wraps in a future result of type T which can be a Failure
It is closely related to Promise, Promise is one way to
generate a Future. Promise generate a Future and later
fulfill it.
16. Future/Promise
val p = promise[Int]
val f = p.future
def producer = {
println("Begin producer")
Thread.sleep(3000)
val r = 100 //produce an Int
p success r
println("end producer")
}
def consumer = {
println("Begin consumer")
f onSuccess {
case r => println("receive product: " + r.toString)
}
println("end consumer")
}
def test2 = {
consumer
producer
}
get result as:
Begin consumer
end consumer
Begin producer
(after 3 secs)
end producer
receive product: 100
17. Future
Future is also a monadic type, you can in fact do for
comprehension on Futures.
Basically, it will give you the ability to specify how to use
the data inside the futures before it really have a value.
If one of the value is a failure, it will automatically propagate
downstream until you want to handle it case by case.
If you have dependency between the futures (based on
parameter chain), it will automatically wait.
18. Future
def xFut: Future[Int] = future {
Thread.sleep(10000);
println("x happened");
10
}.flatMap(i => Future.successful(i + 1))
def yFut(a: Int) : Future[Int] = future {
println("y begin")
Thread.sleep(6000);
println("y happened " + a);
20
}
def zFut(a: Int): Future[Int] = future {
println("z begin")
Thread.sleep(5000);
println("z hapenned " + a);
30
}
result is:
(after 10 secs) x happened
(immediately after) y begin
(immediately after) z begin
(after 5 secs) z hapenned 11
(after 1 secs) y happened 11
(after 4 secs)
The end
def test = {
val xf = xFut
val result: Future[(Int, (Int, Int))] =
for {
x <- xf
a <- af(x)
} yield (x, a)
Thread.sleep(20000)
println("nThe end")
}
def af: Int => Future[(Int, Int)] = a =>
{
val yf = yFut(a)
val zf = zFut(a)
for {
y <- yf
z <- zf
} yield ((y,z))
}
19. External Effect
def sideEffect(x: Int): Int = {
println(x)
x+1
}
This is a function has side effect, you can not really use its
result to substitute it in code (no referential transparency)
For a pure FP, you can not have this, what can you do?
20. IO monad
wrap in the IO side effect and
produces description of the IO
effect (without executing), and
then at the end, let some
interpreter do the job based on
the description.
So you have a pure core, and a
non pure shell for you program.
trait IO[+A] {
self =>
def run: A
def map[B](f: A => B): IO[B] =
new IO[B] { def run = f(self.run) }
def flatMap[B](f: A => IO[B]): IO[B] =
new IO[B] { def run = f(self.run).run }
}
object IO {
def unit[A](a: => A): IO[A] = new IO[A] { def run = a }
def flatMap[A,B](fa: IO[A])(f: A => IO[B]) = fa flatMap f
def apply[A](a: => A): IO[A] = unit(a)
}
21. IO monad in action
def ReadLine: IO[String] = IO { readLine }
def PrintLine(msg: String): IO[Unit] = IO { println(msg) }
def fahrenheitToCelsius(f: Double): Double =
(f - 32) * 5.0/9.0
def converter: IO[Unit] = for {
_ <- PrintLine("Enter a temperature in degrees fahrenheit: ")
d <- ReadLine.map(_.toDouble)
_ <- PrintLine(fahrenheitToCelsius(d).toString)
} yield ()
get
IO[Unit] = IO$$anon$2@2a9d61bf
converter.run
This will really run it.
22. IO monad
Can be expanded to aggregate different
source, distribute to different destination
Can even expanded to Future like async
operation.
23. Internal state
def rollDie: Int = {
val rng = new scala.util.Random
rng.nextInt(6)
}
This is not pure (can return different value based on same
input), and this is wrong (return 0 to 5), and hard to test
(correct 5 out of 6 times)
For a pure FP, you can not have this, what can you do?
24. State monad
sealed trait State[S,A] { self =>
def run(s: S): (A,S)
def map[B](f: A => B): State[S,B] = new State[S,B] {
def run(s: S) = {
val (a, s1) = self.run(s)
(f(a), s1)
}
}
def flatMap[B](f: A => State[S,B]): State[S,B] = new
State[S,B] {
def run(s: S) = {
val (a, s1) = self.run(s)
f(a).run(s1)
}
}
}
object State {
def apply[S,A](f: S => (A,S) ) = {
new State[S,A] {
def run(s: S): (A,S) = f(s)
}
}
def unit[S, A](a: A): State[S, A] =
State(s => (a, s))
def get[S]: State[S, S] = State(s => (s, s))
def set[S](s: S): State[S, Unit] = State(_ => ((), s))
def modify[S](f: S => S): State[S, Unit] = for {
s <- get
_ <- set(f(s))
} yield ()
}
25. State monad
basically, we wrap in the internal state S,
transition take a state, produce a output and a
new state.
It will not run until you ask it run with a state. So
it like IO monad, provide a description of the
transition flow and delay the execution. Before
execution, you can combine it in any way.
26. State monad in action
trait RNG {
def nextInt: (Int, RNG)
}
case class Simple(seed: Long) extends RNG{
def nextInt: (Int, RNG) = {
val newSeed = (seed * 0x5DEECE66DL + 0xBL) & 0xFFFFFFFFFFFFL
val nextRNG = Simple(newSeed)
val n = (newSeed >>> 16).toInt
(n, nextRNG)
}
}
type Rand[A] = State[RNG, A]
val int: Rand[Int] = State(_.nextInt)
generate new random generators:
val posInt = int.map[Int]{ i:Int => if (i < 0) -(i + 1) else i }
def positiveLessThan(n: Int): Rand[Int] = posInt.flatMap {
i => {
val mod = i % n
if (i + (n-1) - mod > 0) State.unit(mod) else positiveLessThan(n)
}}
positiveLessThan(6).run(Simple(5))
produce: 0 (now we can test it)
chain of state transitions: produce 3 result from one initial state
def test4 =
for {
x <- int
y <- int
z <- posInt
} yield ((x , y , z))
test4.run(Simple(1)) produce ((384748,-1151252339,549383846),
Simple(245470556921330))
27. State monad
State monad can in fact be expanded to accept
an input for transition, (A, S) => (B, S), a
powerful State Machine
State monad can also be expanded so that we
can use the Scala static type system to check if
any internal variable leaked outside (we can
have local variable, but still immutable from
outside)
28. for unit and flatMap
Just to remind that although we used for comprehension for all examples, for comprehension is in fact
just syntax sugar for unit/flatMap in Scala
for {
r1 <- m1
r2 <- m2
…….
rx <- mx
} yield (f(r1, r2, ….., rx))
is always the translated by compiler to
m1.flatMap {
r1 => m2.flatMap {
r2 => m3.flatMap {
……..
r x-1 => mx.flatMap {
rx => unit(f(r1, r2, ….., rx))
}
……..
}
29. Monad
All the types we introduced in this session are all monadic
types.
So what is a monad:
● an abstract construction in Category Theory
● an abstract structure of can do a sequence of chained
operations in FP
● a higher kinded types (type of types) in Scala
Let us see the formal definition
30. Monad
// id function:
// def id[A](a: A): A = a
// compose function:
// def compose[A,B,C](f: B => C, g: A => B): A => C =
// a => f(g(a))
trait Functor[F[_]] {
def map[A,B](fa: F[A])(f: A => B): F[B]
}
// Functor Law
// identity: map(x)(id) == x
// composition: map(a)(compose(f, g)) == map(map(a,g), f)
trait Monad[F[_]] extends Functor[F] {
def unit[A](a: => A): F[A]
def flatMap[A,B](ma: F[A])(f: A => F[B]): F[B]
override def map[A,B](ma: F[A])(f: A => B): F[B] =
flatMap(ma)(a => unit(f(a)))
}
// Monad Law
// left identity: f(a) == flatmap(unit(a), f)
// right identity: a == flatMap(a, x => unit(x))
// associativity: flatMap(a, x => flatMap(f(x), g)) == flatMap(flatMap(a, f), g)
31. Higher Kinded Type
[F[ _ ]] is called Higher Kinded Type in Scala, basically a type of types.
Compare to normal [A], this basically says we have a type F that will be used in
code, and F itself is a type that can use F[A], where A is a value type.
Use the value constructor to make a comparison:
proper first-order higher-order
value 10 (x: Int) => x (f(Int => Int)) => f(10)
type String List Monad
32. Monad Laws
As a formal definition of a structure, Monad is
basically a group of types that can implement
unit/flatMap function that match the signature in
the previous slide.
But that is not enough, we also have law that
Monad type need to fulfill so that we know our
implementation of unit/flatMap is correct.
33. Monad Laws
// Monad Law
// left identity: f(a) == flatmap(unit(a), f)
// right identity: a == flatMap(a, x => unit(x))
// associativity: flatMap(a, x => flatMap(f(x), g)) == flatMap(flatMap(a, f), g)
As the name suggest, associative law means flatMap
operation obey the associative law similar to plus/multiple
(a+b) + c = a + (b+c)
As the name suggest, identity laws basically means we
have a unit function that server as a identity in monad, like
0 in addition, which similar to x + 0 = x, and 0 + x = x
34. Still, what is a Monad
Now see all these formal definition, still what is a Monad for us programmer? and Why we need them?
def unit[A](a: => A): M[A]
def flatMap[A,B](ma: M[A])(f: A => M[B]): M[B]
A bit long explanation here:
Monad seems just like a wrapper, it wraps in a basic type (A here), and put into a context M, generate
a richer type (M[A] here). unit function does this.
We care about the value of type A in context M, but we hate part of the context that is troublesome.
The troublesome part in the context M make us lose the composability for values of type A in
context M (make us not be able to combine functions generate value of type A). So we wrap in the
value and troublesome part together into context M, and now we can combine functions that generate
M[A], just as if the troublesome part is gone. That is what flatMap does.
Using unit and flatMap, we regain the composability for values of type A in context M, which is
kind of what monad brings us, and it specifically useful in pure FP as side effect are the things prevent
clean combination of functions.
35. Example monads in our talk
Context Troublesome Part
List multiple value
Option can have empty value
Try can have error
Either can be another unintended (error message etc.) value
Stream multiple value and also not accessible until touched
Future can have error and also have latency to be availuable
IO input/output side effect
State internal states side effect