SlideShare a Scribd company logo
1 of 21
Download to read offline
Abstracting	over	Execution																		
with	Higher	Kinded	Types																							
and	how	to	remain	Purely	Functional
study	aid	for	the	introductory	chapter	of		
Functional	Programming	for	Mortals	with	Scalaz
supplemented	with	code	from	https://github.com/fommil/fpmortals
the	book	by	Sam	Halliday
@fommil
@philip_schwarzslides	by
We want to interact with the user over the command line interface. We
can read what the user types and we can write a message to them.
trait TerminalSync {
def read: String
def write(t: String): Unit
}
trait TerminalAsync {
def read: Future[String]
def write(t: String): Future[Unit]
}
How do we write generic code that does something as simple as echo
the user’s input synchronously or asynchronously depending on our
runtime implementation?
Sam	Halliday
@fommil
We can solve the problem with a common parent using the higher kinded types Scala language feature, which allow us to use a type
constructor in our type parameters, which looks like C[_]. This is a way of saying that whatever C is, it must take a type parameter.
e.g. List is a type constructor because it takes a type (e.g. Int) and constructs a type (List[Int]).
Sam	Halliday
@fommil
trait Terminal[C[_]] {
def read: C[String]
def write(t: String): C[Unit]
}
object TerminalSync extends Terminal[Now] {
def read: String = StdIn.readLine
def write(t: String): Unit = println(t)
}
class TerminalAsync(implicit EC: ExecutionContext) extends Terminal[Future] {
def read: Future[String] = Future { StdIn.readLine }
def write(t: String): Future[Unit] = Future { println(t) }
}
We want to define Terminal for a type constructor C[_]. By defining Now to
construct to its type parameter (like Id), we can implement a common interface for
synchronous and asynchronous terminals.
There is this one weird trick we can use when we want to ignore the type constructor.
We can define a type alias to be equal to its parameter: type Id[T] = T.
We can think of C as a context because we say “in
the context of executing Now” or “in the Future”
type Now[X] = X
/* Read (from a terminal) a string (in some context C, with some effect C)
Then write the string (back to the terminal)
Finally return the string (within its enclosing context/effect C) */
def echo[C[_]](t:Terminal[C]): C[String] = {
val context: C[String] = t.read
val text: String = /* ... extract the string contained in context C, but how? we know nothing about C ... */ ???
t.write(text)
context
}
trait Terminal[C[_]] {
def read: C[String]
def write(t: String): C[Unit]
}
We want to write generic code to echo the
user’s input synchronously or asynchronously
depending on our runtime implementation,
but we know nothing about C and we can’t do
anything with a C[String].
Sam	Halliday @fommil
What we need is a kind of execution environment that lets us call a method returning C[T] and then be able to do
something with the T, including calling another method on Terminal. We also need a way of wrapping a value as a C[_].
letting	us	write
trait Execution[C[_]] {
def doAndThen[A, B](c: C[A])(f: A => C[B]): C[B]
def create[B](b: B): C[B]
}
def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
e.doAndThen(t.read) { text:String =>
e.doAndThen(t.write(text)) { _:Unit =>
e.create(text)
}
}
We can now share the echo implementation between synchronous and asynchronous
codepaths. We can write a mock implementation of Terminal[Now] and use it in our tests
without any timeouts. Implementations of Execution[Now] and Execution[Future] are
reusable by generic methods like echo.
This signature works well
@philip_schwarz
trait Terminal[C[_]] {
def read: C[String]
def write(t: String): C[Unit]
}
trait Execution[C[_]] {
def doAndThen[A, B](c: C[A])(f: A => C[B]): C[B]
def create[B](b: B): C[B]
}
def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
e.doAndThen(t.read) { text:String =>
e.doAndThen(t.write(text)) { _:Unit =>
e.create(text)
}
}
@philip_schwarz
This doAndThen invocation extracts the text string
(unboxes it) from the context/effect C returned by
t.read, passes it to a function (the rest of the echo
method’s logic), and returns the result of that function,
which is in the same context/effect C.
This doAndThen invocation extracts the contents of a
context/effect C (unboxes them) returned by t.write
(in this case a Unit which we don’t care about),
passes it to a function (the rest of the echo method’s
logic), and returns the result of that function, which is
in the same context/effect C.
create lifts a text string into a context/effect C (puts it in a box – boxes the string in context/effect C)
Sam	Halliday @fommil
trait Terminal[C[_]] {
def read: C[String]
def write(t: String): C[Unit]
}
trait Execution[C[_]] {
def doAndThen[A, B](c: C[A])(f: A => C[B]): C[B]
def create[B](b: B): C[B]
}
object TerminalSync extends Terminal[Now] {
def read: Now[String] = StdIn.readLine
def write(t: String): Now[Unit] = println(t)
}
implicit val executionNow = new Execution[Now] {
def doAndThen[A, B](c: A)(f: A => Now[B]): Now[B] = f(c)
def create[B](b: B): Now[B] = b
}
val input: Now[String] = echo[Now]
implicit val terminalNow: Terminal[Now] = TerminalSync
def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
e.doAndThen(t.read) { text:String =>
e.doAndThen(t.write(text)) { _:Unit =>
e.create(text)
}
}
Implementations	of	 Terminal[Now]]and Execution[Now]
are	reusable	by	generic	methods	like	echo
Implementing	and	instantiating		Execution[Now]
instantiating		Terminal[Now]
implementing	Terminal[Now]
instantiating	generic	method		echo[C[_]] for	Now and	invoking	it	with	implicit	
terminalNow :Terminal[Now] and	executionNow:Execution[Now]
Sam	Halliday @fommil
type Now[X] = X
running	the	echo method	in	the	context	of executing	Now
trait Terminal[C[_]] {
def read: C[String]
def write(t: String): C[Unit]
}
trait Execution[C[_]] {
def doAndThen[A, B](c: C[A])(f: A => C[B]): C[B]
def create[B](b: B): C[B]
}
object TerminalSync extends Terminal[Now] {
def read: String = StdIn.readLine
def write(t: String): Unit = println(t)
}
implicit val executionNow = new Execution[Now] {
def doAndThen[A, B](c: A)(f: A => B): B = f(c)
def create[B](b: B): B = b
}
val input: String = echo[Now]
def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
e.doAndThen(t.read) { text:String =>
e.doAndThen(t.write(text)) { _:Unit =>
e.create(text)
}
}
Implementations	of	 Terminal[Now]]and	Execution[Now]
are	reusable	by	generic	methods	like	echo
Implementing	and	instantiating		Execution[Now]
instantiating		Terminal[Now]
implementing	Terminal[Now]
Sam	Halliday @fommil
type Now[X] = X
same	as	previous	slide	but	with	Now[String] and Now[B] replaced	with	String and	B since	Now[X] = X
implicit val terminalNow: Terminal[Now] = TerminalSync
instantiating	generic	method		echo[C[_]] for	Now and	invoking	it	with	implicit	
terminalNow :Terminal[Now] and	executionNow:Execution[Now]
trait Terminal[C[_]] {
def read: C[String]
def write(t: String): C[Unit]
}
trait Execution[C[_]] {
def doAndThen[A, B](c: C[A])(f: A => C[B]): C[B]
def create[B](b: B): C[B]
}
object TerminalAsync extends Terminal[Future] {
def read:Future[String]=Future{ StdIn.readLine }
def write(t:String):Future[Unit]=Future{ println(t) }
}
implicit val executionFuture = new Execution[Future] {
def doAndThen[A,B](c:A)(f:A=>Future[B]):Future[B] =
c flatMap f
def create[B](b:B):Future[B] =
Future.successful(b)
}
val input: Future[String] = echo[Future]
implicit val terminalFuture:Terminal[Future]=TerminalAsync
def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
e.doAndThen(t.read) { text:String =>
e.doAndThen(t.write(text)) { _:Unit =>
e.create(text)
}
}
Implementations	of	 Terminal[Future]]and Execution[Future]
are	reusable	by	generic	methods	like	echo
Implementing	and	instantiating		Execution[Future]
instantiating		Terminal[Future]
implementing	Terminal[Future]
instantiating	generic	method		echo[C[_]] for	Future and	invoking	it	with	implicit	
terminalFuture :Terminal[Future] and	executionFuture:Execution[Future]
Sam	Halliday @fommil
running	the	echo method	in	the	Future
def greet[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
e.doAndThen(t.write(s"Hello, what is your name?")) { _ =>
e.doAndThen(t.read) { name =>
e.doAndThen(t.write(s"Nice to meet you, $name.")) { _ =>
e.create(name)
}
}
}
println("About to run greet[Now]")
val name: String = greet[Now]
println(s"The result was $name.")
running	a	greet	method	in	the	context	of executing	Now	
About to run greet[Now]
Hello, what is your name?
John
Nice to meet you, John.
The result was John
@philip_schwarz
def greet[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
e.doAndThen(t.write(s"Hello, what is your name?")) { _ =>
e.doAndThen(t.read) { name =>
e.doAndThen(t.write(s"Nice to meet you, $name.")) { _ =>
e.create(name)
}
}
}
val futureName: Future[String] = greet[Future]
Try {
Await.result(futureName, Duration(10,"seconds"))
} match {
case Success(name) => println(s"The result was $name")
case Failure(e) => e match {
case e:TimeoutException => println(s"Error: no name was entered within the allowed time window!")
case _ => println(s"The following exception occurred running greet[Future]: $e")
}
}
running	the	greet	method	in	the	Future
About to run greet[Future]
Hello, what is your name?
John
Nice to meet you, John.
The result was John
Hello, what is your name?
Error: no name was entered within the allowed time window!
@philip_schwarz
Sam	Halliday
@fommil
In the previous section, we abstracted over execution and defined
echo[Id] and echo[Future].
We might reasonably expect that calling any echo will not perform any
side effects, because it is pure. However, if we use Future or Id as the
execution context, our application will start listening to stdin:
val futureEcho: Future[String] = echo[Future]
We have broken purity and are no longer writing FP code: futureEcho
is the result of running echo once. Future conflates the definition of a
program with interpreting it (running it). As a result, applications built
with Future are difficult to reason about.
…
An expression is referentially transparent if it can be replaced with its
corresponding value without changing the program’s behaviour.
…
We cannot replace echo[Future] with a value, such as val
futureEcho, since the pesky user will probably type something
different the second time.
Functional Programming is the act of writing programs with pure functions. Pure functions have three
properties:
• Total: return a value for every possible input
• Deterministic: return the same value for the same input
• Inculpable: no (direct) interaction with the world or program state.
…
The kinds of things that break these properties are side effects…
We write pure functions by avoiding exceptions, and interacting with the world only through a safe F[_]
execution context.
…
We	can	define	a	simple	safe	F[_]	execution	context which	lazily evaluates	a	thunk.	
IO is	just	a	data	structure	that	references	(potentially)	impure	code,	it	isn’t	actually	running	anything.	We	
can	implement	Terminal[IO]
final class IO[A] private (val interpret: () => A) {
def map[B](f: A => B): IO[B] = IO(f(interpret()))
def flatMap[B](f: A => IO[B]): IO[B] = IO(f(interpret()).interpret())
}
object IO {
def apply[A](a: =>A): IO[A] = new IO(() => a)
}
Sam	Halliday @fommil
object TerminalIO extends Terminal[IO] {
def read: IO[String] = IO { StdIn.readLine }
def write(t: String): IO[Unit] = IO { println(t) }
}
final class IO[A] private (val interpret: () => A) {
def map[B](f: A => B): IO[B] = IO(f(interpret()))
def flatMap[B](f: A => IO[B]): IO[B] = IO(f(interpret()).interpret())
}
object IO {
def apply[A](a: =>A): IO[A] = new IO(() => a)
}
trait Terminal[C[_]] {
def read: C[String]
def write(t: String): C[Unit]
}
trait Execution[C[_]] {
def doAndThen[A, B](c: C[A])(f: A => C[B]): C[B]
def create[B](b: B): C[B]
}
running	the	echo
method	using IO
object TerminalIO extends Terminal[IO] {
def read: IO[String] =
IO { StdIn.readLine }
def write(t: String): IO[Unit] =
IO { println(t) }
}
implicit val io: Terminal[IO] = TerminalIO
implicit val deferred: Execution[IO] = new Execution[IO] {
def doAndThen[A, B](c: IO[A])(f: A => IO[B]): IO[B] =
c flatMap f
def create[B](b: B): IO[B] =
IO(b)
}
def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
e.doAndThen(t.read) { text:String =>
e.doAndThen(t.write(text)) { _:Unit =>
e.create(text)
}
}
val delayed: IO[String] = echo[IO]
val input = delayed.interpret()
Sam	Halliday @fommil
Implementing	and	instantiating		Execution[IO]
instantiating		Terminal[IO]
instantiating	generic	method		echo[C[_]] for	IO and	invoking	it	with	
implicit	io:Terminal[IO] and		deferred:Execution[IO]
Sam	Halliday @fommilWe can call echo[IO] to get back a value
val delayed: IO[String] = echo[IO]
This val delayed can be reused, it is just the definition of the work to be done. We can map the
String and compose additional programs, much as we would map over a Future. IO keeps us
honest that we are depending on some interaction with the world, but does not prevent us from
accessing the output of that interaction.
The impure code inside the IO is only evaluated when we .interpret() the value, which is an
impure action
delayed.interpret()
An application composed of IO programs is only interpreted once, in the main method, which is
also called the end of the world.
In this book, we expand on the concepts introduced in this chapter and show how to write
maintainable, pure functions, that achieve your business’s objectives.
def greet[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
e.doAndThen(t.write(s"Hello, what is your name?")) { _ =>
e.doAndThen(t.read) { name =>
e.doAndThen(t.write(s"Nice to meet you, $name.")) { _ =>
e.create(name)
}
}
}
println("About to run greet[IO]")
val deferredName : IO[String] = greet[IO]
println("About to execute the result of greet[IO]")
val name: String = deferredName.interpret()
println(s"The result was $name.")
running	the	greet	method	using	IO
About to run greet[IO]
About to execute the result of greet[IO]
Hello, what is your name?
John
Nice to meet you, John.
The result was John.
@philip_schwarz
def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
e.doAndThen(t.read) { text:String =>
e.doAndThen(t.write(text)) { _:Unit =>
e.create(text)
}
}
Sam	Halliday
@fommil
The code for echo is horrible! Let’s clean it up.
The implicit class Scala language feature gives C some methods. We’ll call these methods
flatMap and map for reasons that will become clearer in a moment. Each method takes an
implicit Execution[C], but this is nothing more than the flatMap and map that you’re used
to on Seq, Option and Future.
implicit class Ops[A, C[_]](c: C[A]) {
def flatMap[B](f: A => C[B])(implicit e: Execution[C]): C[B] =
e.doAndThen(c)(f)
def map[B](f: A => B)(implicit e: Execution[C]): C[B] =
e.doAndThen(c)(f andThen e.create)
}
def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
t.read.flatMap { in: String =>
t.write(in).map { _: Unit =>
in
}
}
implicit val executionFuture = new Execution[Future] {
def doAndThen[A,B](c:A)(f:A=>Future[B]):Future[B] = c flatMap f
def create[B](b:B):Future[B] = Future.successful(b)
}
We can now reveal why we used flatMap as the method name: it lets us use a for comprehension,
which is just syntax sugar over nested flatMap and map.
Our Execution has the same signature as a trait in scalaz called Monad, except doAndThen is
flatMap and create is pure. We say that C is monadic when there is an implicit Monad[C] available.
In addition, scalaz has the Id type alias.
The takeaway is: if we write methods that operate on monadic types, then we can write sequential
code that abstracts over its execution context. Here, we have shown an abstraction over synchronous
and asynchronous execution but it can also be for the purpose of more rigorous error handling (where
C[_] is Either[Error, _]), managing access to volatile state, performing I/O, or auditing of the session.
def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
for {
in <- t.read
_ <- t.write(in)
} yield in
Sam	Halliday @fommil
implicit class Ops[A, C[_]](c: C[A]) {
def flatMap[B](f: A => C[B])(implicit e: Execution[C]): C[B] =
e.doAndThen(c)(f)
def map[B](f: A => B)(implicit e: Execution[C]): C[B] =
e.doAndThen(c)(f andThen e.create)
}
implicit val executionNow: Execution[Now] = new Execution[Now] {
def doAndThen[A, B](c: A)(f: A => B): B = f(c)
def create[B](b: B): B = b
}
implicit def executionFuture (implicit EC: ExecutionContext): Execution[Future] = new Execution[Future] {
def doAndThen[A, B](c: Future[A])(f: A => Future[B]): Future[B] = c flatMap f
def create[B](b: B): Future[B] = Future.successful(b)
}
implicit val deferred: Execution[IO] = new Execution[IO] {
def doAndThen[A, B](c: IO[A])(f: A => IO[B]): IO[B] = c flatMap f
def create[B](b: B): IO[B] = IO(b)
}
Sam	Halliday @fommil
def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
for {
in <- t.read
_ <- t.write(in)
} yield in
together with implicit class Ops,
these implicit methods allow us to
call Terminal[C] methods in a for
comprehension.
Running	the	greet method	using	Option
class TerminalMaybe extends Terminal[Option] {
def read: Option[String] = Some(StdIn.readLine).filter(_.trim != "")
def write(t: String): Option[Unit] = Some(println(t))
}
implicit val maybeExecution: Execution[Option] = new Execution[Option] {
def doAndThen[A, B](c: Option[A])(f: A => Option[B]): Option[B] = c flatMap f
def create[B](b: B): Option[B] = Some(b)
}
implicit val maybeTerminal: Terminal[Option] = new TerminalMaybe
def greet[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
for {
_ <- t.write(s"Hello, what is your name?")
name <- t.read
_ <- t.write(s"Nice to meet you, $name.")
} yield name
println("About to run greet[Option]")
val maybeName: Option[String] = greet[Option]
maybeName match {
case Some(name) => println(s"The result was $name.")
case None => println("No name was entered!")
}
About to run greet[Option]
Hello, what is your name?
John
Nice to meet you, John.
The result was John.
About to run greet[Option]
Hello, what is your name?
No name was entered!
@philip_schwarz
Running	the	greet method	using	Either
type ValidatedName[A] = Either[String, A]
class TerminalValidated extends Terminal[ValidatedName] {
def read: ValidatedName[String] = Right(StdIn.readLine).filterOrElse(!_.isEmpty, "not supplied!")
.filterOrElse(_.head.isUpper, "not capitalised!")
.filterOrElse(_.length > 1, "too short!")
def write(t: String): ValidatedName[Unit] = Right(println(t))
}
implicit val validated: Execution[ValidatedName] = new Execution[ValidatedName] {
def doAndThen[A, B](c: ValidatedName[A])(f: A => ValidatedName[B]): ValidatedName[B] = c flatMap f
def create[B](b: B): ValidatedName[B] = Right(b)
}
implicit val validated: Terminal[ValidatedName] = new TerminalValidated
def greet[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
for {
_ <- t.write(s"Hello, what is your name?")
name <- t.read
_ <- t.write(s"Nice to meet you, $name.")
} yield name
println("About to run greet[ValidatedName]")
val validatedName: ValidatedName[String] = greet[ValidatedName]
validatedName match {
case Right(name) => println(s"The result was $name.")
case Left(error) => println(s"Invalid Name: $error.")
}
About to run greet[ValidatedName]
Hello, what is your name?
John
Nice to meet you, John.
The result was John.
About to run greet[ValidatedName]
Hello, what is your name?
john
Invalid Name: not capitalised!
@philip_schwarz
Just	for	fun,	running	the	greet method	using	List
class TerminalMany extends Terminal[List] {
def read: List[String] = StdIn.readLine.split(",").toList
def write(t: String): List[Unit] = List(println(t))
}
implicit val manyExecution: Execution[List] = new Execution[List] {
def doAndThen[A, B](c: List[A])(f: A => List[B]): List[B] = c flatMap f
def create[B](b: B): List[B] = List(b)
}
implicit val manyTerminal: Terminal[List] = new TerminalMany
def greet[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
for {
_ <- t.write(s"Hello, what is your name?")
name <- t.read
_ <- t.write(s"Nice to meet you, $name.")
} yield name
println("About to run greet[List]")
val names: List[String] = greet[List]
println(s"The result was $names.")
About to run greet[List]
Hello, what is your name?
John,Jane
Nice to meet you, John.
Nice to meet you, Jane.
The result was List(John, Jane).
@philip_schwarz

More Related Content

What's hot

C cheat sheet for varsity (extreme edition)
C cheat sheet for varsity (extreme edition)C cheat sheet for varsity (extreme edition)
C cheat sheet for varsity (extreme edition)Saifur Rahman
 
Type header file in c++ and its function
Type header file in c++ and its functionType header file in c++ and its function
Type header file in c++ and its functionFrankie Jones
 
Advanced Tagless Final - Saying Farewell to Free
Advanced Tagless Final - Saying Farewell to FreeAdvanced Tagless Final - Saying Farewell to Free
Advanced Tagless Final - Saying Farewell to FreeLuka Jacobowitz
 
Principled Error Handling with FP
Principled Error Handling with FPPrincipled Error Handling with FP
Principled Error Handling with FPLuka Jacobowitz
 
Testing in the World of Functional Programming
Testing in the World of Functional ProgrammingTesting in the World of Functional Programming
Testing in the World of Functional ProgrammingLuka Jacobowitz
 
Learning C++ - Functions in C++ 3
Learning C++ - Functions  in C++ 3Learning C++ - Functions  in C++ 3
Learning C++ - Functions in C++ 3Ali Aminian
 
Python-02| Input, Output & Import
Python-02| Input, Output & ImportPython-02| Input, Output & Import
Python-02| Input, Output & ImportMohd Sajjad
 
Fp in scala with adts
Fp in scala with adtsFp in scala with adts
Fp in scala with adtsHang Zhao
 
Functional programming in Python
Functional programming in PythonFunctional programming in Python
Functional programming in PythonColin Su
 
Fp in scala with adts part 2
Fp in scala with adts part 2Fp in scala with adts part 2
Fp in scala with adts part 2Hang Zhao
 
Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)stasimus
 

What's hot (20)

C cheat sheet for varsity (extreme edition)
C cheat sheet for varsity (extreme edition)C cheat sheet for varsity (extreme edition)
C cheat sheet for varsity (extreme edition)
 
Type header file in c++ and its function
Type header file in c++ and its functionType header file in c++ and its function
Type header file in c++ and its function
 
Arrays
ArraysArrays
Arrays
 
Advanced Tagless Final - Saying Farewell to Free
Advanced Tagless Final - Saying Farewell to FreeAdvanced Tagless Final - Saying Farewell to Free
Advanced Tagless Final - Saying Farewell to Free
 
Console i/o for c++
Console i/o for c++Console i/o for c++
Console i/o for c++
 
Pointer
PointerPointer
Pointer
 
Managing console input
Managing console inputManaging console input
Managing console input
 
Principled Error Handling with FP
Principled Error Handling with FPPrincipled Error Handling with FP
Principled Error Handling with FP
 
Testing in the World of Functional Programming
Testing in the World of Functional ProgrammingTesting in the World of Functional Programming
Testing in the World of Functional Programming
 
Learning C++ - Functions in C++ 3
Learning C++ - Functions  in C++ 3Learning C++ - Functions  in C++ 3
Learning C++ - Functions in C++ 3
 
Managing console
Managing consoleManaging console
Managing console
 
DATA TYPE IN PYTHON
DATA TYPE IN PYTHONDATA TYPE IN PYTHON
DATA TYPE IN PYTHON
 
Python programming : Standard Input and Output
Python programming : Standard Input and OutputPython programming : Standard Input and Output
Python programming : Standard Input and Output
 
Python-02| Input, Output & Import
Python-02| Input, Output & ImportPython-02| Input, Output & Import
Python-02| Input, Output & Import
 
Fp in scala with adts
Fp in scala with adtsFp in scala with adts
Fp in scala with adts
 
Functional programming in Python
Functional programming in PythonFunctional programming in Python
Functional programming in Python
 
Fp in scala with adts part 2
Fp in scala with adts part 2Fp in scala with adts part 2
Fp in scala with adts part 2
 
Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)
 
Array notes
Array notesArray notes
Array notes
 
C++ theory
C++ theoryC++ theory
C++ theory
 

Similar to Abstracting over Execution with Higher Kinded Types

Diploma ii cfpc u-4 function, storage class and array and strings
Diploma ii  cfpc u-4 function, storage class and array and stringsDiploma ii  cfpc u-4 function, storage class and array and strings
Diploma ii cfpc u-4 function, storage class and array and stringsRai University
 
Btech i pic u-4 function, storage class and array and strings
Btech i pic u-4 function, storage class and array and stringsBtech i pic u-4 function, storage class and array and strings
Btech i pic u-4 function, storage class and array and stringsRai University
 
Functions torage class and array and strings-
Functions torage class and array and strings-Functions torage class and array and strings-
Functions torage class and array and strings-aneebkmct
 
Mcai pic u 4 function, storage class and array and strings
Mcai pic u 4 function, storage class and array and stringsMcai pic u 4 function, storage class and array and strings
Mcai pic u 4 function, storage class and array and stringsRai University
 
function, storage class and array and strings
 function, storage class and array and strings function, storage class and array and strings
function, storage class and array and stringsRai University
 
Bsc cs i pic u-4 function, storage class and array and strings
Bsc cs i pic u-4 function, storage class and array and stringsBsc cs i pic u-4 function, storage class and array and strings
Bsc cs i pic u-4 function, storage class and array and stringsRai University
 
C programming session 01
C programming session 01C programming session 01
C programming session 01Dushmanta Nath
 
C language by Dr. D. R. Gholkar
C language by Dr. D. R. GholkarC language by Dr. D. R. Gholkar
C language by Dr. D. R. GholkarPRAVIN GHOLKAR
 
Reduce course notes class xii
Reduce course notes class xiiReduce course notes class xii
Reduce course notes class xiiSyed Zaid Irshad
 
Lecture 15_Strings and Dynamic Memory Allocation.pptx
Lecture 15_Strings and  Dynamic Memory Allocation.pptxLecture 15_Strings and  Dynamic Memory Allocation.pptx
Lecture 15_Strings and Dynamic Memory Allocation.pptxJawadTanvir
 
Monads - Dublin Scala meetup
Monads - Dublin Scala meetupMonads - Dublin Scala meetup
Monads - Dublin Scala meetupMikhail Girkin
 
(Lect. 2 & 3) Introduction to C.ppt
(Lect. 2 & 3) Introduction to C.ppt(Lect. 2 & 3) Introduction to C.ppt
(Lect. 2 & 3) Introduction to C.pptatulchaudhary821
 

Similar to Abstracting over Execution with Higher Kinded Types (20)

String_C.pptx
String_C.pptxString_C.pptx
String_C.pptx
 
Programming in C.pptx
Programming in C.pptxProgramming in C.pptx
Programming in C.pptx
 
Diploma ii cfpc u-4 function, storage class and array and strings
Diploma ii  cfpc u-4 function, storage class and array and stringsDiploma ii  cfpc u-4 function, storage class and array and strings
Diploma ii cfpc u-4 function, storage class and array and strings
 
Btech i pic u-4 function, storage class and array and strings
Btech i pic u-4 function, storage class and array and stringsBtech i pic u-4 function, storage class and array and strings
Btech i pic u-4 function, storage class and array and strings
 
Functions torage class and array and strings-
Functions torage class and array and strings-Functions torage class and array and strings-
Functions torage class and array and strings-
 
Mcai pic u 4 function, storage class and array and strings
Mcai pic u 4 function, storage class and array and stringsMcai pic u 4 function, storage class and array and strings
Mcai pic u 4 function, storage class and array and strings
 
function, storage class and array and strings
 function, storage class and array and strings function, storage class and array and strings
function, storage class and array and strings
 
string , pointer
string , pointerstring , pointer
string , pointer
 
Bsc cs i pic u-4 function, storage class and array and strings
Bsc cs i pic u-4 function, storage class and array and stringsBsc cs i pic u-4 function, storage class and array and strings
Bsc cs i pic u-4 function, storage class and array and strings
 
C programming session 01
C programming session 01C programming session 01
C programming session 01
 
Tut1
Tut1Tut1
Tut1
 
C language by Dr. D. R. Gholkar
C language by Dr. D. R. GholkarC language by Dr. D. R. Gholkar
C language by Dr. D. R. Gholkar
 
UNIT-II CP DOC.docx
UNIT-II CP DOC.docxUNIT-II CP DOC.docx
UNIT-II CP DOC.docx
 
C notes.pdf
C notes.pdfC notes.pdf
C notes.pdf
 
Reduce course notes class xii
Reduce course notes class xiiReduce course notes class xii
Reduce course notes class xii
 
Lecture 15_Strings and Dynamic Memory Allocation.pptx
Lecture 15_Strings and  Dynamic Memory Allocation.pptxLecture 15_Strings and  Dynamic Memory Allocation.pptx
Lecture 15_Strings and Dynamic Memory Allocation.pptx
 
Monads - Dublin Scala meetup
Monads - Dublin Scala meetupMonads - Dublin Scala meetup
Monads - Dublin Scala meetup
 
14 strings
14 strings14 strings
14 strings
 
CP Handout#8
CP Handout#8CP Handout#8
CP Handout#8
 
(Lect. 2 & 3) Introduction to C.ppt
(Lect. 2 & 3) Introduction to C.ppt(Lect. 2 & 3) Introduction to C.ppt
(Lect. 2 & 3) Introduction to C.ppt
 

More from Philip Schwarz

Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Folding Cheat Sheet #3 - third in a series
Folding Cheat Sheet #3 - third in a seriesFolding Cheat Sheet #3 - third in a series
Folding Cheat Sheet #3 - third in a seriesPhilip Schwarz
 
Folding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a seriesFolding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a seriesPhilip Schwarz
 
Folding Cheat Sheet #1 - first in a series
Folding Cheat Sheet #1 - first in a seriesFolding Cheat Sheet #1 - first in a series
Folding Cheat Sheet #1 - first in a seriesPhilip Schwarz
 
Scala Left Fold Parallelisation - Three Approaches
Scala Left Fold Parallelisation- Three ApproachesScala Left Fold Parallelisation- Three Approaches
Scala Left Fold Parallelisation - Three ApproachesPhilip Schwarz
 
Tagless Final Encoding - Algebras and Interpreters and also Programs
Tagless Final Encoding - Algebras and Interpreters and also ProgramsTagless Final Encoding - Algebras and Interpreters and also Programs
Tagless Final Encoding - Algebras and Interpreters and also ProgramsPhilip Schwarz
 
Fusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with ViewsFusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with ViewsPhilip Schwarz
 
A sighting of traverse_ function in Practical FP in Scala
A sighting of traverse_ function in Practical FP in ScalaA sighting of traverse_ function in Practical FP in Scala
A sighting of traverse_ function in Practical FP in ScalaPhilip Schwarz
 
A sighting of traverseFilter and foldMap in Practical FP in Scala
A sighting of traverseFilter and foldMap in Practical FP in ScalaA sighting of traverseFilter and foldMap in Practical FP in Scala
A sighting of traverseFilter and foldMap in Practical FP in ScalaPhilip Schwarz
 
A sighting of sequence function in Practical FP in Scala
A sighting of sequence function in Practical FP in ScalaA sighting of sequence function in Practical FP in Scala
A sighting of sequence function in Practical FP in ScalaPhilip Schwarz
 
N-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets CatsN-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets CatsPhilip Schwarz
 
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...Philip Schwarz
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...Philip Schwarz
 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an examplePhilip Schwarz
 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an examplePhilip Schwarz
 
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...Philip Schwarz
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...Philip Schwarz
 
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...Philip Schwarz
 
Jordan Peterson - The pursuit of meaning and related ethical axioms
Jordan Peterson - The pursuit of meaning and related ethical axiomsJordan Peterson - The pursuit of meaning and related ethical axioms
Jordan Peterson - The pursuit of meaning and related ethical axiomsPhilip Schwarz
 
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...Philip Schwarz
 

More from Philip Schwarz (20)

Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Folding Cheat Sheet #3 - third in a series
Folding Cheat Sheet #3 - third in a seriesFolding Cheat Sheet #3 - third in a series
Folding Cheat Sheet #3 - third in a series
 
Folding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a seriesFolding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a series
 
Folding Cheat Sheet #1 - first in a series
Folding Cheat Sheet #1 - first in a seriesFolding Cheat Sheet #1 - first in a series
Folding Cheat Sheet #1 - first in a series
 
Scala Left Fold Parallelisation - Three Approaches
Scala Left Fold Parallelisation- Three ApproachesScala Left Fold Parallelisation- Three Approaches
Scala Left Fold Parallelisation - Three Approaches
 
Tagless Final Encoding - Algebras and Interpreters and also Programs
Tagless Final Encoding - Algebras and Interpreters and also ProgramsTagless Final Encoding - Algebras and Interpreters and also Programs
Tagless Final Encoding - Algebras and Interpreters and also Programs
 
Fusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with ViewsFusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with Views
 
A sighting of traverse_ function in Practical FP in Scala
A sighting of traverse_ function in Practical FP in ScalaA sighting of traverse_ function in Practical FP in Scala
A sighting of traverse_ function in Practical FP in Scala
 
A sighting of traverseFilter and foldMap in Practical FP in Scala
A sighting of traverseFilter and foldMap in Practical FP in ScalaA sighting of traverseFilter and foldMap in Practical FP in Scala
A sighting of traverseFilter and foldMap in Practical FP in Scala
 
A sighting of sequence function in Practical FP in Scala
A sighting of sequence function in Practical FP in ScalaA sighting of sequence function in Practical FP in Scala
A sighting of sequence function in Practical FP in Scala
 
N-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets CatsN-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets Cats
 
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...
 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
 
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
 
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
 
Jordan Peterson - The pursuit of meaning and related ethical axioms
Jordan Peterson - The pursuit of meaning and related ethical axiomsJordan Peterson - The pursuit of meaning and related ethical axioms
Jordan Peterson - The pursuit of meaning and related ethical axioms
 
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c...
 

Recently uploaded

What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...aditisharan08
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsMehedi Hasan Shohan
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 

Recently uploaded (20)

What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software Solutions
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 

Abstracting over Execution with Higher Kinded Types

  • 2. We want to interact with the user over the command line interface. We can read what the user types and we can write a message to them. trait TerminalSync { def read: String def write(t: String): Unit } trait TerminalAsync { def read: Future[String] def write(t: String): Future[Unit] } How do we write generic code that does something as simple as echo the user’s input synchronously or asynchronously depending on our runtime implementation? Sam Halliday @fommil
  • 3. We can solve the problem with a common parent using the higher kinded types Scala language feature, which allow us to use a type constructor in our type parameters, which looks like C[_]. This is a way of saying that whatever C is, it must take a type parameter. e.g. List is a type constructor because it takes a type (e.g. Int) and constructs a type (List[Int]). Sam Halliday @fommil trait Terminal[C[_]] { def read: C[String] def write(t: String): C[Unit] } object TerminalSync extends Terminal[Now] { def read: String = StdIn.readLine def write(t: String): Unit = println(t) } class TerminalAsync(implicit EC: ExecutionContext) extends Terminal[Future] { def read: Future[String] = Future { StdIn.readLine } def write(t: String): Future[Unit] = Future { println(t) } } We want to define Terminal for a type constructor C[_]. By defining Now to construct to its type parameter (like Id), we can implement a common interface for synchronous and asynchronous terminals. There is this one weird trick we can use when we want to ignore the type constructor. We can define a type alias to be equal to its parameter: type Id[T] = T. We can think of C as a context because we say “in the context of executing Now” or “in the Future” type Now[X] = X
  • 4. /* Read (from a terminal) a string (in some context C, with some effect C) Then write the string (back to the terminal) Finally return the string (within its enclosing context/effect C) */ def echo[C[_]](t:Terminal[C]): C[String] = { val context: C[String] = t.read val text: String = /* ... extract the string contained in context C, but how? we know nothing about C ... */ ??? t.write(text) context } trait Terminal[C[_]] { def read: C[String] def write(t: String): C[Unit] } We want to write generic code to echo the user’s input synchronously or asynchronously depending on our runtime implementation, but we know nothing about C and we can’t do anything with a C[String]. Sam Halliday @fommil What we need is a kind of execution environment that lets us call a method returning C[T] and then be able to do something with the T, including calling another method on Terminal. We also need a way of wrapping a value as a C[_]. letting us write trait Execution[C[_]] { def doAndThen[A, B](c: C[A])(f: A => C[B]): C[B] def create[B](b: B): C[B] } def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] = e.doAndThen(t.read) { text:String => e.doAndThen(t.write(text)) { _:Unit => e.create(text) } } We can now share the echo implementation between synchronous and asynchronous codepaths. We can write a mock implementation of Terminal[Now] and use it in our tests without any timeouts. Implementations of Execution[Now] and Execution[Future] are reusable by generic methods like echo. This signature works well @philip_schwarz
  • 5. trait Terminal[C[_]] { def read: C[String] def write(t: String): C[Unit] } trait Execution[C[_]] { def doAndThen[A, B](c: C[A])(f: A => C[B]): C[B] def create[B](b: B): C[B] } def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] = e.doAndThen(t.read) { text:String => e.doAndThen(t.write(text)) { _:Unit => e.create(text) } } @philip_schwarz This doAndThen invocation extracts the text string (unboxes it) from the context/effect C returned by t.read, passes it to a function (the rest of the echo method’s logic), and returns the result of that function, which is in the same context/effect C. This doAndThen invocation extracts the contents of a context/effect C (unboxes them) returned by t.write (in this case a Unit which we don’t care about), passes it to a function (the rest of the echo method’s logic), and returns the result of that function, which is in the same context/effect C. create lifts a text string into a context/effect C (puts it in a box – boxes the string in context/effect C) Sam Halliday @fommil
  • 6. trait Terminal[C[_]] { def read: C[String] def write(t: String): C[Unit] } trait Execution[C[_]] { def doAndThen[A, B](c: C[A])(f: A => C[B]): C[B] def create[B](b: B): C[B] } object TerminalSync extends Terminal[Now] { def read: Now[String] = StdIn.readLine def write(t: String): Now[Unit] = println(t) } implicit val executionNow = new Execution[Now] { def doAndThen[A, B](c: A)(f: A => Now[B]): Now[B] = f(c) def create[B](b: B): Now[B] = b } val input: Now[String] = echo[Now] implicit val terminalNow: Terminal[Now] = TerminalSync def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] = e.doAndThen(t.read) { text:String => e.doAndThen(t.write(text)) { _:Unit => e.create(text) } } Implementations of Terminal[Now]]and Execution[Now] are reusable by generic methods like echo Implementing and instantiating Execution[Now] instantiating Terminal[Now] implementing Terminal[Now] instantiating generic method echo[C[_]] for Now and invoking it with implicit terminalNow :Terminal[Now] and executionNow:Execution[Now] Sam Halliday @fommil type Now[X] = X running the echo method in the context of executing Now
  • 7. trait Terminal[C[_]] { def read: C[String] def write(t: String): C[Unit] } trait Execution[C[_]] { def doAndThen[A, B](c: C[A])(f: A => C[B]): C[B] def create[B](b: B): C[B] } object TerminalSync extends Terminal[Now] { def read: String = StdIn.readLine def write(t: String): Unit = println(t) } implicit val executionNow = new Execution[Now] { def doAndThen[A, B](c: A)(f: A => B): B = f(c) def create[B](b: B): B = b } val input: String = echo[Now] def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] = e.doAndThen(t.read) { text:String => e.doAndThen(t.write(text)) { _:Unit => e.create(text) } } Implementations of Terminal[Now]]and Execution[Now] are reusable by generic methods like echo Implementing and instantiating Execution[Now] instantiating Terminal[Now] implementing Terminal[Now] Sam Halliday @fommil type Now[X] = X same as previous slide but with Now[String] and Now[B] replaced with String and B since Now[X] = X implicit val terminalNow: Terminal[Now] = TerminalSync instantiating generic method echo[C[_]] for Now and invoking it with implicit terminalNow :Terminal[Now] and executionNow:Execution[Now]
  • 8. trait Terminal[C[_]] { def read: C[String] def write(t: String): C[Unit] } trait Execution[C[_]] { def doAndThen[A, B](c: C[A])(f: A => C[B]): C[B] def create[B](b: B): C[B] } object TerminalAsync extends Terminal[Future] { def read:Future[String]=Future{ StdIn.readLine } def write(t:String):Future[Unit]=Future{ println(t) } } implicit val executionFuture = new Execution[Future] { def doAndThen[A,B](c:A)(f:A=>Future[B]):Future[B] = c flatMap f def create[B](b:B):Future[B] = Future.successful(b) } val input: Future[String] = echo[Future] implicit val terminalFuture:Terminal[Future]=TerminalAsync def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] = e.doAndThen(t.read) { text:String => e.doAndThen(t.write(text)) { _:Unit => e.create(text) } } Implementations of Terminal[Future]]and Execution[Future] are reusable by generic methods like echo Implementing and instantiating Execution[Future] instantiating Terminal[Future] implementing Terminal[Future] instantiating generic method echo[C[_]] for Future and invoking it with implicit terminalFuture :Terminal[Future] and executionFuture:Execution[Future] Sam Halliday @fommil running the echo method in the Future
  • 9. def greet[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] = e.doAndThen(t.write(s"Hello, what is your name?")) { _ => e.doAndThen(t.read) { name => e.doAndThen(t.write(s"Nice to meet you, $name.")) { _ => e.create(name) } } } println("About to run greet[Now]") val name: String = greet[Now] println(s"The result was $name.") running a greet method in the context of executing Now About to run greet[Now] Hello, what is your name? John Nice to meet you, John. The result was John @philip_schwarz
  • 10. def greet[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] = e.doAndThen(t.write(s"Hello, what is your name?")) { _ => e.doAndThen(t.read) { name => e.doAndThen(t.write(s"Nice to meet you, $name.")) { _ => e.create(name) } } } val futureName: Future[String] = greet[Future] Try { Await.result(futureName, Duration(10,"seconds")) } match { case Success(name) => println(s"The result was $name") case Failure(e) => e match { case e:TimeoutException => println(s"Error: no name was entered within the allowed time window!") case _ => println(s"The following exception occurred running greet[Future]: $e") } } running the greet method in the Future About to run greet[Future] Hello, what is your name? John Nice to meet you, John. The result was John Hello, what is your name? Error: no name was entered within the allowed time window! @philip_schwarz
  • 11. Sam Halliday @fommil In the previous section, we abstracted over execution and defined echo[Id] and echo[Future]. We might reasonably expect that calling any echo will not perform any side effects, because it is pure. However, if we use Future or Id as the execution context, our application will start listening to stdin: val futureEcho: Future[String] = echo[Future] We have broken purity and are no longer writing FP code: futureEcho is the result of running echo once. Future conflates the definition of a program with interpreting it (running it). As a result, applications built with Future are difficult to reason about. … An expression is referentially transparent if it can be replaced with its corresponding value without changing the program’s behaviour. … We cannot replace echo[Future] with a value, such as val futureEcho, since the pesky user will probably type something different the second time.
  • 12. Functional Programming is the act of writing programs with pure functions. Pure functions have three properties: • Total: return a value for every possible input • Deterministic: return the same value for the same input • Inculpable: no (direct) interaction with the world or program state. … The kinds of things that break these properties are side effects… We write pure functions by avoiding exceptions, and interacting with the world only through a safe F[_] execution context. … We can define a simple safe F[_] execution context which lazily evaluates a thunk. IO is just a data structure that references (potentially) impure code, it isn’t actually running anything. We can implement Terminal[IO] final class IO[A] private (val interpret: () => A) { def map[B](f: A => B): IO[B] = IO(f(interpret())) def flatMap[B](f: A => IO[B]): IO[B] = IO(f(interpret()).interpret()) } object IO { def apply[A](a: =>A): IO[A] = new IO(() => a) } Sam Halliday @fommil object TerminalIO extends Terminal[IO] { def read: IO[String] = IO { StdIn.readLine } def write(t: String): IO[Unit] = IO { println(t) } }
  • 13. final class IO[A] private (val interpret: () => A) { def map[B](f: A => B): IO[B] = IO(f(interpret())) def flatMap[B](f: A => IO[B]): IO[B] = IO(f(interpret()).interpret()) } object IO { def apply[A](a: =>A): IO[A] = new IO(() => a) } trait Terminal[C[_]] { def read: C[String] def write(t: String): C[Unit] } trait Execution[C[_]] { def doAndThen[A, B](c: C[A])(f: A => C[B]): C[B] def create[B](b: B): C[B] } running the echo method using IO object TerminalIO extends Terminal[IO] { def read: IO[String] = IO { StdIn.readLine } def write(t: String): IO[Unit] = IO { println(t) } } implicit val io: Terminal[IO] = TerminalIO implicit val deferred: Execution[IO] = new Execution[IO] { def doAndThen[A, B](c: IO[A])(f: A => IO[B]): IO[B] = c flatMap f def create[B](b: B): IO[B] = IO(b) } def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] = e.doAndThen(t.read) { text:String => e.doAndThen(t.write(text)) { _:Unit => e.create(text) } } val delayed: IO[String] = echo[IO] val input = delayed.interpret() Sam Halliday @fommil Implementing and instantiating Execution[IO] instantiating Terminal[IO] instantiating generic method echo[C[_]] for IO and invoking it with implicit io:Terminal[IO] and deferred:Execution[IO]
  • 14. Sam Halliday @fommilWe can call echo[IO] to get back a value val delayed: IO[String] = echo[IO] This val delayed can be reused, it is just the definition of the work to be done. We can map the String and compose additional programs, much as we would map over a Future. IO keeps us honest that we are depending on some interaction with the world, but does not prevent us from accessing the output of that interaction. The impure code inside the IO is only evaluated when we .interpret() the value, which is an impure action delayed.interpret() An application composed of IO programs is only interpreted once, in the main method, which is also called the end of the world. In this book, we expand on the concepts introduced in this chapter and show how to write maintainable, pure functions, that achieve your business’s objectives.
  • 15. def greet[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] = e.doAndThen(t.write(s"Hello, what is your name?")) { _ => e.doAndThen(t.read) { name => e.doAndThen(t.write(s"Nice to meet you, $name.")) { _ => e.create(name) } } } println("About to run greet[IO]") val deferredName : IO[String] = greet[IO] println("About to execute the result of greet[IO]") val name: String = deferredName.interpret() println(s"The result was $name.") running the greet method using IO About to run greet[IO] About to execute the result of greet[IO] Hello, what is your name? John Nice to meet you, John. The result was John. @philip_schwarz
  • 16. def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] = e.doAndThen(t.read) { text:String => e.doAndThen(t.write(text)) { _:Unit => e.create(text) } } Sam Halliday @fommil The code for echo is horrible! Let’s clean it up. The implicit class Scala language feature gives C some methods. We’ll call these methods flatMap and map for reasons that will become clearer in a moment. Each method takes an implicit Execution[C], but this is nothing more than the flatMap and map that you’re used to on Seq, Option and Future. implicit class Ops[A, C[_]](c: C[A]) { def flatMap[B](f: A => C[B])(implicit e: Execution[C]): C[B] = e.doAndThen(c)(f) def map[B](f: A => B)(implicit e: Execution[C]): C[B] = e.doAndThen(c)(f andThen e.create) } def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] = t.read.flatMap { in: String => t.write(in).map { _: Unit => in } } implicit val executionFuture = new Execution[Future] { def doAndThen[A,B](c:A)(f:A=>Future[B]):Future[B] = c flatMap f def create[B](b:B):Future[B] = Future.successful(b) }
  • 17. We can now reveal why we used flatMap as the method name: it lets us use a for comprehension, which is just syntax sugar over nested flatMap and map. Our Execution has the same signature as a trait in scalaz called Monad, except doAndThen is flatMap and create is pure. We say that C is monadic when there is an implicit Monad[C] available. In addition, scalaz has the Id type alias. The takeaway is: if we write methods that operate on monadic types, then we can write sequential code that abstracts over its execution context. Here, we have shown an abstraction over synchronous and asynchronous execution but it can also be for the purpose of more rigorous error handling (where C[_] is Either[Error, _]), managing access to volatile state, performing I/O, or auditing of the session. def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] = for { in <- t.read _ <- t.write(in) } yield in Sam Halliday @fommil
  • 18. implicit class Ops[A, C[_]](c: C[A]) { def flatMap[B](f: A => C[B])(implicit e: Execution[C]): C[B] = e.doAndThen(c)(f) def map[B](f: A => B)(implicit e: Execution[C]): C[B] = e.doAndThen(c)(f andThen e.create) } implicit val executionNow: Execution[Now] = new Execution[Now] { def doAndThen[A, B](c: A)(f: A => B): B = f(c) def create[B](b: B): B = b } implicit def executionFuture (implicit EC: ExecutionContext): Execution[Future] = new Execution[Future] { def doAndThen[A, B](c: Future[A])(f: A => Future[B]): Future[B] = c flatMap f def create[B](b: B): Future[B] = Future.successful(b) } implicit val deferred: Execution[IO] = new Execution[IO] { def doAndThen[A, B](c: IO[A])(f: A => IO[B]): IO[B] = c flatMap f def create[B](b: B): IO[B] = IO(b) } Sam Halliday @fommil def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] = for { in <- t.read _ <- t.write(in) } yield in together with implicit class Ops, these implicit methods allow us to call Terminal[C] methods in a for comprehension.
  • 19. Running the greet method using Option class TerminalMaybe extends Terminal[Option] { def read: Option[String] = Some(StdIn.readLine).filter(_.trim != "") def write(t: String): Option[Unit] = Some(println(t)) } implicit val maybeExecution: Execution[Option] = new Execution[Option] { def doAndThen[A, B](c: Option[A])(f: A => Option[B]): Option[B] = c flatMap f def create[B](b: B): Option[B] = Some(b) } implicit val maybeTerminal: Terminal[Option] = new TerminalMaybe def greet[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] = for { _ <- t.write(s"Hello, what is your name?") name <- t.read _ <- t.write(s"Nice to meet you, $name.") } yield name println("About to run greet[Option]") val maybeName: Option[String] = greet[Option] maybeName match { case Some(name) => println(s"The result was $name.") case None => println("No name was entered!") } About to run greet[Option] Hello, what is your name? John Nice to meet you, John. The result was John. About to run greet[Option] Hello, what is your name? No name was entered! @philip_schwarz
  • 20. Running the greet method using Either type ValidatedName[A] = Either[String, A] class TerminalValidated extends Terminal[ValidatedName] { def read: ValidatedName[String] = Right(StdIn.readLine).filterOrElse(!_.isEmpty, "not supplied!") .filterOrElse(_.head.isUpper, "not capitalised!") .filterOrElse(_.length > 1, "too short!") def write(t: String): ValidatedName[Unit] = Right(println(t)) } implicit val validated: Execution[ValidatedName] = new Execution[ValidatedName] { def doAndThen[A, B](c: ValidatedName[A])(f: A => ValidatedName[B]): ValidatedName[B] = c flatMap f def create[B](b: B): ValidatedName[B] = Right(b) } implicit val validated: Terminal[ValidatedName] = new TerminalValidated def greet[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] = for { _ <- t.write(s"Hello, what is your name?") name <- t.read _ <- t.write(s"Nice to meet you, $name.") } yield name println("About to run greet[ValidatedName]") val validatedName: ValidatedName[String] = greet[ValidatedName] validatedName match { case Right(name) => println(s"The result was $name.") case Left(error) => println(s"Invalid Name: $error.") } About to run greet[ValidatedName] Hello, what is your name? John Nice to meet you, John. The result was John. About to run greet[ValidatedName] Hello, what is your name? john Invalid Name: not capitalised! @philip_schwarz
  • 21. Just for fun, running the greet method using List class TerminalMany extends Terminal[List] { def read: List[String] = StdIn.readLine.split(",").toList def write(t: String): List[Unit] = List(println(t)) } implicit val manyExecution: Execution[List] = new Execution[List] { def doAndThen[A, B](c: List[A])(f: A => List[B]): List[B] = c flatMap f def create[B](b: B): List[B] = List(b) } implicit val manyTerminal: Terminal[List] = new TerminalMany def greet[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] = for { _ <- t.write(s"Hello, what is your name?") name <- t.read _ <- t.write(s"Nice to meet you, $name.") } yield name println("About to run greet[List]") val names: List[String] = greet[List] println(s"The result was $names.") About to run greet[List] Hello, what is your name? John,Jane Nice to meet you, John. Nice to meet you, Jane. The result was List(John, Jane). @philip_schwarz