SlideShare ist ein Scribd-Unternehmen logo
1 von 11
Downloaden Sie, um offline zu lesen
Scala	collection	methods	flatMap and	flatten are	more	powerful	than	monadic	flatMap and	flatten
A	monad	is	an	implementation	of	one	of	the	minimal	sets	of	monadic	combinators,	satisfying	the	laws	of	associativity	and	identity.	
Here	is	a	monad	trait	implementing	monadic	combinators	unit and	flatMap
trait Monad[F[_]]{
def unit[A](a: ⇒ A): F[A]
def flatMap[A,B](ma: F[A])(f: A ⇒ F[B]): F[B]
def map[A,B](m: F[A])(f: A ⇒ B): F[B] = flatMap(m)(a ⇒ unit(f(a)))
def flatten[A](mma: F[F[A]]): F[A] = flatMap(mma)(ma ⇒ ma)
…
}
And	here	is	a	monad	trait	implementing	monadic	combinators		unit,	map and	flatten
trait Monad[F[_]]{
def unit[A](a: ⇒ A): F[A]
def map[A,B](m: F[A])(f: A ⇒ B): F[B]
def flatten[A](mma: F[F[A]]): F[A]
def flatMap[A,B](ma: F[A])(f: A ⇒ F[B]): F[B] = flatten(map(ma)(f))
…
}
The	flatten function	takes	an	F[F[A]]	and	returns	an	F[A]
def flatten[A](mma: F[F[A]]): F[A]
What	it	does	is	“remove	a	layer”	of	F.	
The	flatMap function	takes	an	F[A]	and	a	function	from	A	to	F[B]	and	returns	an	F[B]
def flatMap[A,B](ma: F[A])(f: A ⇒ F[B]): F[B]
What	it	does	is	apply	to	each	A	element	of	ma	a	function	f	producing	an	F[B],	but	instead	of	
returning	the	resulting	F[F[B]],	it	flattens	it	and	returns	an	F[B].	
In	the	first	monad	trait,	flatten is	defined	in	terms	of	flatMap:
def flatten[A](mma: F[F[A]]): F[A] = flatMap(mma)(ma => ma)
So	flattening	is	just	flatMapping	the	identity	function x => x.
In	the	second	monad	trait,	flatMap is	defined	in	terms	of	map and	flatten:
def flatMap[A,B](ma: F[A])(f: A ⇒ F[B]): F[B] = flatten(map(ma)(f))
So	flatMapping	a	function	is	just	mapping	the	function	first	and	then	flattening	the	result.
flattening is	just	flatMapping	identity	– flatMapping is	mapping	and	then	flattening
trait Monad[F[A]]{
def unit[A](a: ⇒ A): F[A]
def flatMap[A,B](ma: F[A])(f: A ⇒ F[B]): F[B]
def map[A,B](m: F[A])(f: A ⇒ B): F[B] = flatMap(m)(a ⇒ unit(f(a)))
def flatten[A](mma: F[F[A]]): F[A] = flatMap(mma)(ma ⇒ ma)
}
val listMonad = new Monad[List] {
override def unit[A](a: ⇒ A) = List(a)
override def flatMap[A,B](ma: List[A])(f: A ⇒ List[B]): List[B] = ma flatMap f
}
We	can	now	use	listMonad’s	flatten method	to	flatten	a	List of	Lists	:
assert(listMonad.flatten(List(List(1,2,3),List[Int](),List(4,5,6))) == List(1,2,3,4,5,6))
Similarly	for	other	collections	like	Set,	Vector,	etc:
val setMonad = new Monad[Set] { … }
val vectorMonad = new Monad[Vector] { … }
assert(setMonad.flatten(Set(Set(1,2,3),Set[Int](),Set(4,5,6))) == Set(1,2,3,4,5,6))
assert(vectorMonad.flatten(Vector(Vector(1,2,3),Vector[Int](),Vector(4,5,6))) == Vector(1,2,3,4,5,6))
But	what	we	cannot	do	is	mix	types.	E.g.	we	can’t	flatten	a	List of	Sets:
assert(listMonad.flatten(List(Set(1,2,3),Set[Int](),Set(4,5,6))) == List(1,2,3,4,5,6))
^
error:	type	mismatch;					found:	List[scala.collection.immutable.Set[Int]] required:	List[List[?]]
The	reason	is	that	the	signature	of	flatten	expects	an	F[F[A]],	not	an	F[G[A]].	E.g.	it	expects	a	List[List[A]]	or	a	Set[Set[A]],	not	a	List[Set[A]]
If	we	instantiate	the	first	Monad	trait	using	
List’s	own	flatMap method	then	the	trait	
gives	us	a	flatten method	for	free
We	can	flatten F[F[A]],	but	not	
F[G[A]].	e.g	we	can	flatten
List[List[A]],	not	List[Set[A]].
A	monad	can	flatten	F[F[A]],	but	not	F[G[A]]
trait Monad[F[A]]{
def unit[A](a: ⇒ A): F[A]
def map[A,B](m: F[A])(f: A ⇒ B): F[B]
def flatten[A](mma: F[F[A]]): F[A]
def flatMap[A,B](ma: F[A])(f: A ⇒ F[B]): F[B] = flatten(map(ma)(f))
}
val listMonad = new Monad[List] {
def unit[A](a: ⇒ A): List[A] = List(a)
def map[A,B](m: List[A])(f: A ⇒ B): List[B] = m map f
def flatten[A](mma: List[List[A]]): List[A] = mma.flatten
}
We	can	now	use	listMonad’s	flatMap method,	to	flatmap	a	list	with	a	function	that	creates	a	list:
assert(listMonad.flatMap(List(1,0,4)){case 0 => List[Int]() case x => List(x,x+1,x+2)} == List(1,2,3,4,5,6))
Similarly	for	other	collections	like	Set,	Vector,	etc:
val setMonad = new Monad[Set] { … }
val vectorMonad = new Monad[Vector] { … }
assert(setMonad.flatMap(Set(1,0,4)){case 0 => Set[Int]() case x => Set(x,x+1,x+2)} == Set(1,2,3,4,5,6))
assert(vectorMonad.flatMap(Vector(1,0,4)){case 0 => Vector[Int]() case x => Vector(x,x+1,x+2)} == Vector(1,2,3,4,5,6))
But	what	we	cannot	do	is	mix	types.	E.g.	we	can’t	flatmap	a	List with	a	function	that	creates	a	Set :
assert(listMonad.flatMap(List(1,0,4)){case 0 => Set[Int]() case x => Set(x,x+1,x+2)} == Set(1,2,3,4,5,6))
^ ^
error:	type	mismatch;					found:	scala.collection.immutable.Set[Int] required:	List[?]
The	reason	is	that	the	signature	of	flatMap	operates	on	an	F[A]	and	a	function	that	creates	an	F[B],	not	a	G[B].	E.g.	it	operates	on	a	List[A]	
and	a	function	that	creates	a	List[A],	not	a	Set[A].
If	we	instantiate	the	second	Monad	trait,	using	
List’s	own	map and	flatten methods	then	
the	trait	gives	us	a	flatMap method	for	free
We	can flatMap F[A]	with	a	function	that	
creates	an	F[B],	not	one	that	creates	a	G[B].	
e.g.	we	can flatMap List[A]	with	a	function	
that	creates	a	List[B],	not	one	that	creates	a	
Set[B].
A	monad	can	flatMap F[A]	with	a	function	returning	F[B],	but	not	with	a	function	returning	G[B]
The	flatten and	flatMap methods	of	our	monad	instances	don’t	support	mixing	of	types.	e.g.	the	following	does	not	compile:	
assert(listMonad.flatten(List(Set(1,2,3),Set[Int](),Set(4,5,6))) == List(1,2,3,4,5,6))
assert(listMonad.flatMap(List(1,0,4)){case 0 => Set[Int]() case x => Set(x,x+1,x+2)} == List(1,2,3,4,5,6))
The	flatten and	flatMap methods	of	List, on	the	other	hand,	do	allow	mixing	of	types.	e.g.	the	following	works:
assert(List(Set(1,2,3),Set[Int](),Set(4,5,6)).flatten == List(1,2,3,4,5,6))
assert(List(1,0,4).flatMap{case 0 => Set[Int]() case x => Set(x,x+1,x+2)} == List(1,2,3,4,5,6))
In	fact List supports	even	more	mixing	of	types:
assert(List(Set(1,2,3),Vector[Int](),List(4,5,6)).flatten == List(1,2,3,4,5,6))
assert(List(1,0,4).flatMap{case 0 => Set[Int]() case x => Vector(x,x+1,x+2)} == List(1,2,3,4,5,6))
How	do	the	flatten and	flatMap methods	of	Scala	collections	support	mixing	of	types?
The	monadic	flatten and	flatMap methods	don’t	support	mixing	of	types,	but	the	flatten and	flatMap methods	of	Scala	collections	do
From	https://docs.scala-lang.org/overviews/core/architecture-of-scala-collections.html
Almost	all	collection	operations	are	implemented	in	terms	of traversals and builders.	Traversals	are	handled	by Traversable’s foreach method,	and	building	new	
collections	is	handled	by	instances	of	class Builder.
trait Builder[-Elem, +To] Builders	are	generic	in	both	the	element	type, Elem,	and	in	the	type, To,	of	collections	they	return.
…
You	can	add	an	element x to	a	builder b with b	+=	x.	There’s	also	syntax	to	add	more	than	one	element	at	once,	for	instance b	+= (x,	y).	Adding	another	collection	
with b	++=	xs works	as	for	buffers.	The result() method	returns	a	collection	from	a	builder.
…
[flatMap]	uses	a builder	factory that’s	passed	as	an	additional	implicit	parameter	of	type CanBuildFrom.
def flatMap[B, That](f: A => scala.collection.GenTraversableOnce[B])
(implicit bf: CanBuildFrom[Repr, B, That]): That
…
CanBuildFrom is	a	factory	for	a	builder:
trait CanBuildFrom[-From, -Elem, +To]
CanBuildFrom represents builder factories. It has three type parameters:
• From indicates the type for which this builder factory applies
• Elem indicates the element type of the collection to be built
• To indicates the type of collection to build
From	https://www.scala-lang.org/blog/2017/05/30/tribulations-canbuildfrom.html
CanBuildFrom is probably the most infamous abstraction of the current collections. It is mainly criticised for making scary type signatures.
The	flatMap and	flatten methods	of	Scala	collections	rely	on	traversals,	collection	builders	and	builder	factories
List(1,0,4).flatMap{case 0 => Set[Int]() case x => Set(x,x+1,x+2)}
The	following	implicit	builder	factory in	the	List companion	object	is	selected:
implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, List[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]
def newBuilder[A]: Builder[A, List[A]] = new ListBuffer[A]
The	following flatMap definition	in List is	selected
final override def flatMap[B,That](f:A=>GenTraversableOnce[B])(implicit bf: CanBuildFrom[List[A],B,That]):That
bf:	builder	factory creating	a	builder (a	ListBuffer),	
that	can	be	used	to	build	a	List.
If	the	selected	list	builder	factory bf is	ReusableCBF,	then	List’s	flatMap doesn’t	use	the	factory	at	all!	
Instead,	it	does	its	own	list	building:
For	each	list	element, flatMap adds	(to	the	list	it	is	building)	the	elements	of	the	traversable created	by	
applying	f to	the	list	element.
If	the	selected	builder	factory	is	some	other	factory,	then flatMap delegates	to	the flatMap in		trait	
TraversableLike:
def flatMap[B, That](f: A => GenTraversableOnce[B])
(implicit bf: CanBuildFrom[Repr, B, That]): That = {
def builder = bf(repr)
val b = builder
for (x <- this) b ++= f(x).seq
b.result
}
flatMap first uses builder factory bf to create a list builder. For
each list element, flatMap then gets the builder to add (to the list it
is building) the elements of the traversable (e.g. a Set) created by
applying f to the list element.
How	List’s flatMap method	builds	a	List
ReusableCBF delegates	creation	of	a	builder to	this	method
NOTE:	f does	not	return	a	List,	it	returns	something	
that	can	be	traversed using	its	foreach method.
List’s		flatMap method
NOTE:	f returns	something	that	can	be	
traversed using	its	foreach method
Vector(1,0,4).flatMap{case 0=>Set[Int]() case x=>Set(x,x+1,x+2)}
The	following	implicit	builder	factory in	the	Vector companion	object	is	selected:
def newBuilder[A]: Builder[A, Vector[A]] = new VectorBuilder[A]
implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Vector[A]] =
ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]
The	following	flatMap definition	in	TraversableLike	is	selected:
def flatMap[B, That](f: A => GenTraversableOnce[B])
(implicit bf: CanBuildFrom[Repr, B, That]): That = {
def builder = bf(repr)
val b = builder
for (x <- this) b ++= f(x).seq
b.result
}
bf:	builder	factory	creating	a	builder (a	VectorBuilder)	that	
can	be	used	to	build	a	Vector.
For	each	vector	element,	flatMap gets	VectorBuilder to	add	(to	the	vector	it	is	building)	
the	elements	of	the	traversable (e.g.	a	Set) created	by	applying	f to	the	vector	element.
How	Vector’s	flatMap method	builds	a	Vector
ReusableCBF delegates	creation	of	a	builder	to	this	method
Set(1,0,4).flatMap{case 0=>Vector[Int]() case x=>Vector(x,x+1,x+2)}
The	following	flatMap definition	in	TraversableLike is	selected:
def flatMap[B, That](f: A => GenTraversableOnce[B])
(implicit : CanBuildFrom[Repr, B, That]): That = {
def builder = (repr)
val b = builder
for (x <- this) b ++= f(x).seq
b.result
}
which	delegates	creation	of	a	builder to	the	following	method	in	abstract	class	ImmutableSetFactory
def newBuilder[A]: Builder[A, CC[A]] = new SetBuilder[A, CC[A]](empty[A])
which	delegates	to	the	following	method	in	abstract	class	GenSetFactory
def setCanBuildFrom[A] = new CanBuildFrom[CC[_], A, CC[A]] {
def apply(from: CC[_]) = from match {
case from: Set[_] => from.genericBuilder.asInstanceOf[Builder[A, CC[A]]]
case _ => newBuilder[A]
}
def apply() = newBuilder[A]
}
For	each	set	element,	flatMap gets	SetBuilder to	add	(to	the	set	it	is	building)	the	
elements	of	the	traversable (e.g.	a	Vector)	created	by	applying f to	the	set	element.
How	Set’s	flatMap method	builds	a	Set
The	following	implicit	builder	factory	in	the	Set companion	object	is	selected:
implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Set[A]] = setCanBuildFrom[A]
bf:	builder	factory	creating	a	builder (a	SetBuilder)	
that	can	be	used	to	build	a	Set.
Unlike	the	flatten method	of	our	monad	instances,	the	flatten method	of	Scala	collections,	e.g.	List/Vector/Set,	can	do	the	following:
assert(List(Set(1,2,3),Set[Int](),Set(4,5,6)).flatten == List(1,2,3,4,5,6))
assert(Vector(Set(1,2,3),Set[Int](),Set(4,5,6)).flatten == Vector(1,2,3,4,5,6))
assert(Set(Vector(1,2,3),Vector[Int](),Vector(4,5,6)).flatten == Set(1,2,3,4,5,6))
How	does	the	flatten method	convert	the	nested	collections,	whose	types	differ	from	the	type	of	the	enclosing	collection,	to	collections	of	
the	same	type	as	the	enclosing	collection?
In	all	the	above	three	cases,	flatten is	implemented	in	trait	GenericTraversableTemplate:
def flatten[B](implicit asTraversable: A => GenTraversableOnce[B]): CC[B] = {
val b = genericBuilder[B]
for (xs <- sequential)
b ++= asTraversable(xs).seq
b.result()
}
When	the	enclosing	collection	is	List,	the	following	builder	in	the	List companion	object	is	used:	
def newBuilder[A]: Builder[A, List[A]] = new ListBuffer[A]
When	the	enclosing	collection	is	Vector,	the	following	builder	in	the	Vector companion	object	is	used:
def newBuilder[A]: Builder[A, Vector[A]] = new VectorBuilder[A]
When	the	enclosing	collection	is	Set,	the	following	builder	in	abstract	class	ImmutableSetFactory is	used:
def newBuilder[A]: Builder[A, CC[A]] = new SetBuilder[A, CC[A]](empty[A])
For	each	collection-typed	element	(e.g.	a	Set or	Vector),	flatMap gets	the builder (the ListBuffer /	
VectorBuilder /	SetBuilder)	to	add	(to	the	List /	Vector /	Set it	is	building)	the	elements	of	the	
collection-typed	element	(a	traversable whose	elements	can	be	accessed	with	its	foreach method).
an	implicit	conversion	which	asserts	that	the	element	type	of	this	collection,	e.g.	List/Vector/Set, is	a	
GenTraversableOnce,	which	provides	a	foreach method	giving	access	to	its	elements.
How	the	flatten	method	of	a	collection	handles	nested	collections	of	types	differing	from	that	of	the	collection
b:	a	collection	builder - the	type	of	builder depends	on	the	type	of	the	collection	to	be	built,	see	bottom	of	slide
The	flatMap and	flatten methods	of	Scala	collections	can	operate	on	elements	of	many	types,	including	Option,	Range and	Map
Option,	Range and	Map are	all	examples	of GenTraversableOnce
import scala.collection.GenTraversableOnce
val o: GenTraversableOnce[Int] = Some(3)
val r: GenTraversableOnce[Int] = Range(1,3)
val m: GenTraversableOnce[(String,Int)] = Map("1"->1,"2"->2)
So	the flatMap and	flatten methods	of	a	collection,	e.g.	a	List,	can	operate	on	those	types:
assert(List(Some(1),None,Some(2),None,Some(3)).flatten
== List(1,2,3))
assert(List(0,1,2).flatMap{case 0 => None case x => Some(x)}
== List(1,2))
assert(List(Range(1,4),Range(4,7)).flatten
== List(1,2,3,4,5,6))
assert(List(0,1,4).flatMap{case 0 => Range(0,0) case x => Range(x,x+3)}
== List(1,2,3,4,5,6))
assert(List(Map("1" -> 1, "2" -> 2), Map[String,Int](), Map("3" -> 3, "4" -> 4)).flatten
== List("1"->1, "2"->2, "3"->3, "4"->4))
assert(List(0,1,3).flatMap{case 0 => Map[String,Int]() case x => Map(s"$x"->x, s"${x+1}"->(x+1))}
== List("1"->1, "2"->2, "3"->3, "4"->4))

Weitere ähnliche Inhalte

Was ist angesagt?

Abstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generatorsAbstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generatorsPhilip Schwarz
 
Monad Transformers - Part 1
Monad Transformers - Part 1Monad Transformers - Part 1
Monad Transformers - Part 1Philip Schwarz
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Philip Schwarz
 
Kleisli composition, flatMap, join, map, unit - implementation and interrelation
Kleisli composition, flatMap, join, map, unit - implementation and interrelationKleisli composition, flatMap, join, map, unit - implementation and interrelation
Kleisli composition, flatMap, join, map, unit - implementation and interrelationPhilip Schwarz
 
Scala. Introduction to FP. Monads
Scala. Introduction to FP. MonadsScala. Introduction to FP. Monads
Scala. Introduction to FP. MonadsKirill Kozlov
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Philip Schwarz
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsPhilip Schwarz
 
Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)stasimus
 
Symmetry in the interrelation of flatMap/foldMap/traverse and flatten/fold/se...
Symmetry in the interrelation of flatMap/foldMap/traverse and flatten/fold/se...Symmetry in the interrelation of flatMap/foldMap/traverse and flatten/fold/se...
Symmetry in the interrelation of flatMap/foldMap/traverse and flatten/fold/se...Philip Schwarz
 
Addendum to ‘Monads do not Compose’
Addendum to ‘Monads do not Compose’ Addendum to ‘Monads do not Compose’
Addendum to ‘Monads do not Compose’ Philip Schwarz
 
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...Philip Schwarz
 
Monads and friends demystified
Monads and friends demystifiedMonads and friends demystified
Monads and friends demystifiedAlessandro Lacava
 
Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020Luka Jacobowitz
 
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
 
Monoids, monoids, monoids
Monoids, monoids, monoidsMonoids, monoids, monoids
Monoids, monoids, monoidsLuka Jacobowitz
 
The Essence of the Iterator Pattern
The Essence of the Iterator PatternThe Essence of the Iterator Pattern
The Essence of the Iterator PatternEric Torreborre
 

Was ist angesagt? (20)

Abstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generatorsAbstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generators
 
Monad Transformers - Part 1
Monad Transformers - Part 1Monad Transformers - Part 1
Monad Transformers - Part 1
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
 
Kleisli composition, flatMap, join, map, unit - implementation and interrelation
Kleisli composition, flatMap, join, map, unit - implementation and interrelationKleisli composition, flatMap, join, map, unit - implementation and interrelation
Kleisli composition, flatMap, join, map, unit - implementation and interrelation
 
Monads do not Compose
Monads do not ComposeMonads do not Compose
Monads do not Compose
 
Scala. Introduction to FP. Monads
Scala. Introduction to FP. MonadsScala. Introduction to FP. Monads
Scala. Introduction to FP. Monads
 
Monad Fact #2
Monad Fact #2Monad Fact #2
Monad Fact #2
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and Cats
 
Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)
 
Symmetry in the interrelation of flatMap/foldMap/traverse and flatten/fold/se...
Symmetry in the interrelation of flatMap/foldMap/traverse and flatten/fold/se...Symmetry in the interrelation of flatMap/foldMap/traverse and flatten/fold/se...
Symmetry in the interrelation of flatMap/foldMap/traverse and flatten/fold/se...
 
Addendum to ‘Monads do not Compose’
Addendum to ‘Monads do not Compose’ Addendum to ‘Monads do not Compose’
Addendum to ‘Monads do not Compose’
 
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
 
Monads and friends demystified
Monads and friends demystifiedMonads and friends demystified
Monads and friends demystified
 
Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020Monoids, Monoids, Monoids - ScalaLove 2020
Monoids, Monoids, Monoids - ScalaLove 2020
 
Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)
 
Monoids, monoids, monoids
Monoids, monoids, monoidsMonoids, monoids, monoids
Monoids, monoids, monoids
 
The Essence of the Iterator Pattern
The Essence of the Iterator PatternThe Essence of the Iterator Pattern
The Essence of the Iterator Pattern
 
Monad Fact #4
Monad Fact #4Monad Fact #4
Monad Fact #4
 
Array
ArrayArray
Array
 

Ähnlich wie Scala collection methods flatMap and flatten are more powerful than monadic flatMap and flatten (download for better quality)

(2015 06-16) Three Approaches to Monads
(2015 06-16) Three Approaches to Monads(2015 06-16) Three Approaches to Monads
(2015 06-16) Three Approaches to MonadsLawrence Evans
 
The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)Eric Torreborre
 
Monad presentation scala as a category
Monad presentation   scala as a categoryMonad presentation   scala as a category
Monad presentation scala as a categorysamthemonad
 
Advance Scala - Oleg Mürk
Advance Scala - Oleg MürkAdvance Scala - Oleg Mürk
Advance Scala - Oleg MürkPlanet OS
 
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
 
From Functor Composition to Monad Transformers
From Functor Composition to Monad TransformersFrom Functor Composition to Monad Transformers
From Functor Composition to Monad TransformersHermann Hueck
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2Hang Zhao
 
Functional programming with_scala
Functional programming with_scalaFunctional programming with_scala
Functional programming with_scalaRaymond Tay
 
하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4Kwang Yul Seo
 
Monad and Algebraic Design in Functional Programming
Monad and Algebraic Design in Functional ProgrammingMonad and Algebraic Design in Functional Programming
Monad and Algebraic Design in Functional ProgrammingNamuk Park
 
Practical scalaz
Practical scalazPractical scalaz
Practical scalazoxbow_lakes
 
Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Scalac
 
Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Piotr Paradziński
 
Oh, All the things you'll traverse
Oh, All the things you'll traverseOh, All the things you'll traverse
Oh, All the things you'll traverseLuka Jacobowitz
 
Essence of the iterator pattern
Essence of the iterator patternEssence of the iterator pattern
Essence of the iterator patternMarkus Klink
 

Ähnlich wie Scala collection methods flatMap and flatten are more powerful than monadic flatMap and flatten (download for better quality) (20)

(2015 06-16) Three Approaches to Monads
(2015 06-16) Three Approaches to Monads(2015 06-16) Three Approaches to Monads
(2015 06-16) Three Approaches to Monads
 
The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)
 
Frp2016 3
Frp2016 3Frp2016 3
Frp2016 3
 
Monad presentation scala as a category
Monad presentation   scala as a categoryMonad presentation   scala as a category
Monad presentation scala as a category
 
Practical cats
Practical catsPractical cats
Practical cats
 
Advance Scala - Oleg Mürk
Advance Scala - Oleg MürkAdvance Scala - Oleg Mürk
Advance Scala - Oleg Mürk
 
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...
 
From Functor Composition to Monad Transformers
From Functor Composition to Monad TransformersFrom Functor Composition to Monad Transformers
From Functor Composition to Monad Transformers
 
Thesis PPT
Thesis PPTThesis PPT
Thesis PPT
 
Thesis
ThesisThesis
Thesis
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
 
Functional programming with_scala
Functional programming with_scalaFunctional programming with_scala
Functional programming with_scala
 
Introduction to MATLAB
Introduction to MATLABIntroduction to MATLAB
Introduction to MATLAB
 
하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4하스켈 프로그래밍 입문 4
하스켈 프로그래밍 입문 4
 
Monad and Algebraic Design in Functional Programming
Monad and Algebraic Design in Functional ProgrammingMonad and Algebraic Design in Functional Programming
Monad and Algebraic Design in Functional Programming
 
Practical scalaz
Practical scalazPractical scalaz
Practical scalaz
 
Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...
 
Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...
 
Oh, All the things you'll traverse
Oh, All the things you'll traverseOh, All the things you'll traverse
Oh, All the things you'll traverse
 
Essence of the iterator pattern
Essence of the iterator patternEssence of the iterator pattern
Essence of the iterator pattern
 

Mehr von 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
 
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
 
Defining filter using (a) recursion (b) folding with S, B and I combinators (...
Defining filter using (a) recursion (b) folding with S, B and I combinators (...Defining filter using (a) recursion (b) folding with S, B and I combinators (...
Defining filter using (a) recursion (b) folding with S, B and I combinators (...Philip Schwarz
 

Mehr von 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
 
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...
 
Defining filter using (a) recursion (b) folding with S, B and I combinators (...
Defining filter using (a) recursion (b) folding with S, B and I combinators (...Defining filter using (a) recursion (b) folding with S, B and I combinators (...
Defining filter using (a) recursion (b) folding with S, B and I combinators (...
 

Kürzlich hochgeladen

GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptrcbcrtm
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 

Kürzlich hochgeladen (20)

GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.ppt
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 

Scala collection methods flatMap and flatten are more powerful than monadic flatMap and flatten (download for better quality)

  • 1. Scala collection methods flatMap and flatten are more powerful than monadic flatMap and flatten A monad is an implementation of one of the minimal sets of monadic combinators, satisfying the laws of associativity and identity. Here is a monad trait implementing monadic combinators unit and flatMap trait Monad[F[_]]{ def unit[A](a: ⇒ A): F[A] def flatMap[A,B](ma: F[A])(f: A ⇒ F[B]): F[B] def map[A,B](m: F[A])(f: A ⇒ B): F[B] = flatMap(m)(a ⇒ unit(f(a))) def flatten[A](mma: F[F[A]]): F[A] = flatMap(mma)(ma ⇒ ma) … } And here is a monad trait implementing monadic combinators unit, map and flatten trait Monad[F[_]]{ def unit[A](a: ⇒ A): F[A] def map[A,B](m: F[A])(f: A ⇒ B): F[B] def flatten[A](mma: F[F[A]]): F[A] def flatMap[A,B](ma: F[A])(f: A ⇒ F[B]): F[B] = flatten(map(ma)(f)) … }
  • 2. The flatten function takes an F[F[A]] and returns an F[A] def flatten[A](mma: F[F[A]]): F[A] What it does is “remove a layer” of F. The flatMap function takes an F[A] and a function from A to F[B] and returns an F[B] def flatMap[A,B](ma: F[A])(f: A ⇒ F[B]): F[B] What it does is apply to each A element of ma a function f producing an F[B], but instead of returning the resulting F[F[B]], it flattens it and returns an F[B]. In the first monad trait, flatten is defined in terms of flatMap: def flatten[A](mma: F[F[A]]): F[A] = flatMap(mma)(ma => ma) So flattening is just flatMapping the identity function x => x. In the second monad trait, flatMap is defined in terms of map and flatten: def flatMap[A,B](ma: F[A])(f: A ⇒ F[B]): F[B] = flatten(map(ma)(f)) So flatMapping a function is just mapping the function first and then flattening the result. flattening is just flatMapping identity – flatMapping is mapping and then flattening
  • 3. trait Monad[F[A]]{ def unit[A](a: ⇒ A): F[A] def flatMap[A,B](ma: F[A])(f: A ⇒ F[B]): F[B] def map[A,B](m: F[A])(f: A ⇒ B): F[B] = flatMap(m)(a ⇒ unit(f(a))) def flatten[A](mma: F[F[A]]): F[A] = flatMap(mma)(ma ⇒ ma) } val listMonad = new Monad[List] { override def unit[A](a: ⇒ A) = List(a) override def flatMap[A,B](ma: List[A])(f: A ⇒ List[B]): List[B] = ma flatMap f } We can now use listMonad’s flatten method to flatten a List of Lists : assert(listMonad.flatten(List(List(1,2,3),List[Int](),List(4,5,6))) == List(1,2,3,4,5,6)) Similarly for other collections like Set, Vector, etc: val setMonad = new Monad[Set] { … } val vectorMonad = new Monad[Vector] { … } assert(setMonad.flatten(Set(Set(1,2,3),Set[Int](),Set(4,5,6))) == Set(1,2,3,4,5,6)) assert(vectorMonad.flatten(Vector(Vector(1,2,3),Vector[Int](),Vector(4,5,6))) == Vector(1,2,3,4,5,6)) But what we cannot do is mix types. E.g. we can’t flatten a List of Sets: assert(listMonad.flatten(List(Set(1,2,3),Set[Int](),Set(4,5,6))) == List(1,2,3,4,5,6)) ^ error: type mismatch; found: List[scala.collection.immutable.Set[Int]] required: List[List[?]] The reason is that the signature of flatten expects an F[F[A]], not an F[G[A]]. E.g. it expects a List[List[A]] or a Set[Set[A]], not a List[Set[A]] If we instantiate the first Monad trait using List’s own flatMap method then the trait gives us a flatten method for free We can flatten F[F[A]], but not F[G[A]]. e.g we can flatten List[List[A]], not List[Set[A]]. A monad can flatten F[F[A]], but not F[G[A]]
  • 4. trait Monad[F[A]]{ def unit[A](a: ⇒ A): F[A] def map[A,B](m: F[A])(f: A ⇒ B): F[B] def flatten[A](mma: F[F[A]]): F[A] def flatMap[A,B](ma: F[A])(f: A ⇒ F[B]): F[B] = flatten(map(ma)(f)) } val listMonad = new Monad[List] { def unit[A](a: ⇒ A): List[A] = List(a) def map[A,B](m: List[A])(f: A ⇒ B): List[B] = m map f def flatten[A](mma: List[List[A]]): List[A] = mma.flatten } We can now use listMonad’s flatMap method, to flatmap a list with a function that creates a list: assert(listMonad.flatMap(List(1,0,4)){case 0 => List[Int]() case x => List(x,x+1,x+2)} == List(1,2,3,4,5,6)) Similarly for other collections like Set, Vector, etc: val setMonad = new Monad[Set] { … } val vectorMonad = new Monad[Vector] { … } assert(setMonad.flatMap(Set(1,0,4)){case 0 => Set[Int]() case x => Set(x,x+1,x+2)} == Set(1,2,3,4,5,6)) assert(vectorMonad.flatMap(Vector(1,0,4)){case 0 => Vector[Int]() case x => Vector(x,x+1,x+2)} == Vector(1,2,3,4,5,6)) But what we cannot do is mix types. E.g. we can’t flatmap a List with a function that creates a Set : assert(listMonad.flatMap(List(1,0,4)){case 0 => Set[Int]() case x => Set(x,x+1,x+2)} == Set(1,2,3,4,5,6)) ^ ^ error: type mismatch; found: scala.collection.immutable.Set[Int] required: List[?] The reason is that the signature of flatMap operates on an F[A] and a function that creates an F[B], not a G[B]. E.g. it operates on a List[A] and a function that creates a List[A], not a Set[A]. If we instantiate the second Monad trait, using List’s own map and flatten methods then the trait gives us a flatMap method for free We can flatMap F[A] with a function that creates an F[B], not one that creates a G[B]. e.g. we can flatMap List[A] with a function that creates a List[B], not one that creates a Set[B]. A monad can flatMap F[A] with a function returning F[B], but not with a function returning G[B]
  • 5. The flatten and flatMap methods of our monad instances don’t support mixing of types. e.g. the following does not compile: assert(listMonad.flatten(List(Set(1,2,3),Set[Int](),Set(4,5,6))) == List(1,2,3,4,5,6)) assert(listMonad.flatMap(List(1,0,4)){case 0 => Set[Int]() case x => Set(x,x+1,x+2)} == List(1,2,3,4,5,6)) The flatten and flatMap methods of List, on the other hand, do allow mixing of types. e.g. the following works: assert(List(Set(1,2,3),Set[Int](),Set(4,5,6)).flatten == List(1,2,3,4,5,6)) assert(List(1,0,4).flatMap{case 0 => Set[Int]() case x => Set(x,x+1,x+2)} == List(1,2,3,4,5,6)) In fact List supports even more mixing of types: assert(List(Set(1,2,3),Vector[Int](),List(4,5,6)).flatten == List(1,2,3,4,5,6)) assert(List(1,0,4).flatMap{case 0 => Set[Int]() case x => Vector(x,x+1,x+2)} == List(1,2,3,4,5,6)) How do the flatten and flatMap methods of Scala collections support mixing of types? The monadic flatten and flatMap methods don’t support mixing of types, but the flatten and flatMap methods of Scala collections do
  • 6. From https://docs.scala-lang.org/overviews/core/architecture-of-scala-collections.html Almost all collection operations are implemented in terms of traversals and builders. Traversals are handled by Traversable’s foreach method, and building new collections is handled by instances of class Builder. trait Builder[-Elem, +To] Builders are generic in both the element type, Elem, and in the type, To, of collections they return. … You can add an element x to a builder b with b += x. There’s also syntax to add more than one element at once, for instance b += (x, y). Adding another collection with b ++= xs works as for buffers. The result() method returns a collection from a builder. … [flatMap] uses a builder factory that’s passed as an additional implicit parameter of type CanBuildFrom. def flatMap[B, That](f: A => scala.collection.GenTraversableOnce[B]) (implicit bf: CanBuildFrom[Repr, B, That]): That … CanBuildFrom is a factory for a builder: trait CanBuildFrom[-From, -Elem, +To] CanBuildFrom represents builder factories. It has three type parameters: • From indicates the type for which this builder factory applies • Elem indicates the element type of the collection to be built • To indicates the type of collection to build From https://www.scala-lang.org/blog/2017/05/30/tribulations-canbuildfrom.html CanBuildFrom is probably the most infamous abstraction of the current collections. It is mainly criticised for making scary type signatures. The flatMap and flatten methods of Scala collections rely on traversals, collection builders and builder factories
  • 7. List(1,0,4).flatMap{case 0 => Set[Int]() case x => Set(x,x+1,x+2)} The following implicit builder factory in the List companion object is selected: implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, List[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]] def newBuilder[A]: Builder[A, List[A]] = new ListBuffer[A] The following flatMap definition in List is selected final override def flatMap[B,That](f:A=>GenTraversableOnce[B])(implicit bf: CanBuildFrom[List[A],B,That]):That bf: builder factory creating a builder (a ListBuffer), that can be used to build a List. If the selected list builder factory bf is ReusableCBF, then List’s flatMap doesn’t use the factory at all! Instead, it does its own list building: For each list element, flatMap adds (to the list it is building) the elements of the traversable created by applying f to the list element. If the selected builder factory is some other factory, then flatMap delegates to the flatMap in trait TraversableLike: def flatMap[B, That](f: A => GenTraversableOnce[B]) (implicit bf: CanBuildFrom[Repr, B, That]): That = { def builder = bf(repr) val b = builder for (x <- this) b ++= f(x).seq b.result } flatMap first uses builder factory bf to create a list builder. For each list element, flatMap then gets the builder to add (to the list it is building) the elements of the traversable (e.g. a Set) created by applying f to the list element. How List’s flatMap method builds a List ReusableCBF delegates creation of a builder to this method NOTE: f does not return a List, it returns something that can be traversed using its foreach method. List’s flatMap method NOTE: f returns something that can be traversed using its foreach method
  • 8. Vector(1,0,4).flatMap{case 0=>Set[Int]() case x=>Set(x,x+1,x+2)} The following implicit builder factory in the Vector companion object is selected: def newBuilder[A]: Builder[A, Vector[A]] = new VectorBuilder[A] implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Vector[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]] The following flatMap definition in TraversableLike is selected: def flatMap[B, That](f: A => GenTraversableOnce[B]) (implicit bf: CanBuildFrom[Repr, B, That]): That = { def builder = bf(repr) val b = builder for (x <- this) b ++= f(x).seq b.result } bf: builder factory creating a builder (a VectorBuilder) that can be used to build a Vector. For each vector element, flatMap gets VectorBuilder to add (to the vector it is building) the elements of the traversable (e.g. a Set) created by applying f to the vector element. How Vector’s flatMap method builds a Vector ReusableCBF delegates creation of a builder to this method
  • 9. Set(1,0,4).flatMap{case 0=>Vector[Int]() case x=>Vector(x,x+1,x+2)} The following flatMap definition in TraversableLike is selected: def flatMap[B, That](f: A => GenTraversableOnce[B]) (implicit : CanBuildFrom[Repr, B, That]): That = { def builder = (repr) val b = builder for (x <- this) b ++= f(x).seq b.result } which delegates creation of a builder to the following method in abstract class ImmutableSetFactory def newBuilder[A]: Builder[A, CC[A]] = new SetBuilder[A, CC[A]](empty[A]) which delegates to the following method in abstract class GenSetFactory def setCanBuildFrom[A] = new CanBuildFrom[CC[_], A, CC[A]] { def apply(from: CC[_]) = from match { case from: Set[_] => from.genericBuilder.asInstanceOf[Builder[A, CC[A]]] case _ => newBuilder[A] } def apply() = newBuilder[A] } For each set element, flatMap gets SetBuilder to add (to the set it is building) the elements of the traversable (e.g. a Vector) created by applying f to the set element. How Set’s flatMap method builds a Set The following implicit builder factory in the Set companion object is selected: implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Set[A]] = setCanBuildFrom[A] bf: builder factory creating a builder (a SetBuilder) that can be used to build a Set.
  • 10. Unlike the flatten method of our monad instances, the flatten method of Scala collections, e.g. List/Vector/Set, can do the following: assert(List(Set(1,2,3),Set[Int](),Set(4,5,6)).flatten == List(1,2,3,4,5,6)) assert(Vector(Set(1,2,3),Set[Int](),Set(4,5,6)).flatten == Vector(1,2,3,4,5,6)) assert(Set(Vector(1,2,3),Vector[Int](),Vector(4,5,6)).flatten == Set(1,2,3,4,5,6)) How does the flatten method convert the nested collections, whose types differ from the type of the enclosing collection, to collections of the same type as the enclosing collection? In all the above three cases, flatten is implemented in trait GenericTraversableTemplate: def flatten[B](implicit asTraversable: A => GenTraversableOnce[B]): CC[B] = { val b = genericBuilder[B] for (xs <- sequential) b ++= asTraversable(xs).seq b.result() } When the enclosing collection is List, the following builder in the List companion object is used: def newBuilder[A]: Builder[A, List[A]] = new ListBuffer[A] When the enclosing collection is Vector, the following builder in the Vector companion object is used: def newBuilder[A]: Builder[A, Vector[A]] = new VectorBuilder[A] When the enclosing collection is Set, the following builder in abstract class ImmutableSetFactory is used: def newBuilder[A]: Builder[A, CC[A]] = new SetBuilder[A, CC[A]](empty[A]) For each collection-typed element (e.g. a Set or Vector), flatMap gets the builder (the ListBuffer / VectorBuilder / SetBuilder) to add (to the List / Vector / Set it is building) the elements of the collection-typed element (a traversable whose elements can be accessed with its foreach method). an implicit conversion which asserts that the element type of this collection, e.g. List/Vector/Set, is a GenTraversableOnce, which provides a foreach method giving access to its elements. How the flatten method of a collection handles nested collections of types differing from that of the collection b: a collection builder - the type of builder depends on the type of the collection to be built, see bottom of slide
  • 11. The flatMap and flatten methods of Scala collections can operate on elements of many types, including Option, Range and Map Option, Range and Map are all examples of GenTraversableOnce import scala.collection.GenTraversableOnce val o: GenTraversableOnce[Int] = Some(3) val r: GenTraversableOnce[Int] = Range(1,3) val m: GenTraversableOnce[(String,Int)] = Map("1"->1,"2"->2) So the flatMap and flatten methods of a collection, e.g. a List, can operate on those types: assert(List(Some(1),None,Some(2),None,Some(3)).flatten == List(1,2,3)) assert(List(0,1,2).flatMap{case 0 => None case x => Some(x)} == List(1,2)) assert(List(Range(1,4),Range(4,7)).flatten == List(1,2,3,4,5,6)) assert(List(0,1,4).flatMap{case 0 => Range(0,0) case x => Range(x,x+3)} == List(1,2,3,4,5,6)) assert(List(Map("1" -> 1, "2" -> 2), Map[String,Int](), Map("3" -> 3, "4" -> 4)).flatten == List("1"->1, "2"->2, "3"->3, "4"->4)) assert(List(0,1,3).flatMap{case 0 => Map[String,Int]() case x => Map(s"$x"->x, s"${x+1}"->(x+1))} == List("1"->1, "2"->2, "3"->3, "4"->4))