SlideShare a Scribd company logo
1 of 4
Download to read offline
Addendum	to	‘Monads	do	not	Compose’	
a temporary addendum to Part 1 of ‘Monads do not Compose’
illustrating an issue raised by Sergei Winitzki
@philip_schwarz
https://www.slideshare.net/pjschwarz/monads-do-not-compose
It is a mistake to think that a traversable monad can be composed with another monad.
It is true that, given `Traversable`, you can implement the monad's methods (pure and flatMap) for the composition with another
monad (as in your slides 21 to 26), but this is a deceptive appearance.
The laws of the `Traversable` typeclass are far insufficient to guarantee the laws of the resulting composed monad. The only
traversable monads that work correctly are Option, Either, and Writer.
It is true that you can implement the type signature of the `swap` function for any `Traversable` monad. However, the `swap` function
for monads needs to satisfy very different and stronger laws than the `sequence` function from the `Traversable` type class.
I'll have to look at the "Book of Monads"; but, if my memory serves, the FPiS book does not derive any of these laws.Sergei	Winitzki
sergei-winitzki-11a6431
Thank you very much for taking the time to raise this concern.
As seen in Part 1, the Book of Monads says “we definitely need a swap function if we want to combine two
monads, but this is not enough. The reason is that a well-typed implementation may lead to a combined
monad that violates one of the monad laws. The list monad is a well-known example of this.”
So it looks like similar concerns apply when Traversable is used to provide the swap function. In FPiS there is no
example of using composeM to automatically wrap a Traversable Monad in any other Monad, so in Part 1 I had
a go and provided an example by composing the Option Monad with the Traversable List Monad. I need to
check if the resulting Monad satisfies the Monad laws.
In the meantime, see the next two slides for an example of the invalid composition of a Monad with a
Traversable Monad. I compose the List Traversable Monad with itself and while in some cases the resulting
Monad satisfies the monadic associative law, in another case (mentioned in the Book of Monads), it doesn’t.
@philip_schwarz
// sample A => F[B] function
val f: String => List[String] = _.split(" ").toList.map(_.capitalize)
assert(f("dog cat rabbit parrot")
== List("Dog", "Cat", "Rabbit", "Parrot"))
// sample B => F[C] function
val g: String => List[Int] = _.toList.map(_.toInt)
assert(g("Cat") == List(67, 97, 116))
// sample C => F[D] function
val h: Int => List[Char] = _.toString.toList
assert(h(102) == List('1', '0', '2'))
// sample A value
val a = "dog cat rabbit parrot"
// sample B value
val b = "Cat"
// sample C value
val c = 67
// sample D value
val d = '6'
// expected value of applying to "dog cat rabbit parrot"
// the kleisli composition of f, g and h
val expected = List(
/* Dog */ '6', '8', '1', '1', '1', '1', '0', '3',
/* Cat */ '6', '7', '9', '7', '1', '1', '6',
/* Rabbit */ '8', '2', '9', '7', '9', '8', '9', '8', '1', '0', '5', '1', '1', '6',
/* Parrot */ '8', '0', '9', '7', '1', '1', '4', '1', '1', '4', '1', '1', '1', '1', '1', '6')
// monadic associative law: x.flatMap(f).flatMap(g) == x.flatMap(a => f(a).flatMap(g))
// alternative formuation using kleisli composition: compose(compose(f, g), h) == compose(f, compose(g, h))
// the traversable list monad satisfies the associative law because its kleisli composition is associative
assert( traversableListMonad.compose(traversableListMonad.compose(f,g),h)("dog cat rabbit parrot") == expected)
assert( traversableListMonad.compose(f,traversableListMonad.compose(g,h))("dog cat rabbit parrot") == expected)
// Kleisli composition (defined on Monad F)
def compose[A,B,C](f: A => F[B], g: B => F[C]): A => F[C] = {
a => flatMap(f(a))(g)
}
// Monad composition
def composeM[G[_],H[_]](implicit G: Monad[G], H: Monad[H], T: Traverse[H]):
Monad[({type f[x] = G[H[x]]})#f] = new Monad[({type f[x] = G[H[x]]})#f] {
def unit[A](a: => A): G[H[A]] = G.unit(H.unit(a))
override def flatMap[A,B](mna: G[H[A]])(f: A => G[H[B]]): G[H[B]] = {
G.flatMap(mna)(na => G.map(T.traverse(na)(f))(H.join))
}
}
// Let's define a traversable List Monad
val traversableListMonad = new Monad[List] with Traverse[List] {
def unit[A](a: => A): List[A] = List(a)
override def flatMap[A,B](ma: List[A])(f: A => List[B]): List[B] = ma flatMap f
override def map[A,B](m: List[A])(f: A => B): List[B] = m map f
override def join[A](mma: List[List[A]]): List[A] = mma.flatten
override def traverse[M[_],A,B](as: List[A])
(f: A => M[B])(implicit M: Applicative[M]): M[List[B]] = {
as.foldRight(M.unit(List[B]()))((a, fbs) => M.map2(f(a), fbs)(_ :: _))
}
}
// compose traversableListMonad with itself
val listListMonad = composeM(traversableListMonad,traversableListMonad,traversableListMonad)
// Now let’s tweak f, g, and h to return a List of a List rather than just a List, so that they are amenable to
// composing using listListMonad’s kleisli composition, whose signature is
// def compose[A,B,C](f: A => List[List[B]], g: B => List[List[C]]): A => List[List[C]]
val ff: String => List[List[String]] = s => List(f(s),f(s))
val gg: String => List[List[Int]] = s => List(g(s),g(s))
val hh: Int => List[List[Char]] = n => List(h(n))
// listListMonad appears to satisfy the associative law
assert( listListMonad.compose(listListMonad.compose(fff,ggg),hhh)("dog cat rabbit parrot") == List.fill(32)(expected))
assert( listListMonad.compose(fff,listListMonad.compose(ggg,hhh))("dog cat rabbit parrot") == List.fill(32)(expected))
// but it doesn't: here is an example (by Petr Pudlak) of a function for which kleisli composition is not associative
def v(n: Int): List[List[Int]] = n match {
case 0 => List(List(0,1))
case 1 => List(List(0),List(1))
}
// listListMonad's kleisli composition is not associative when we compose function v with itself
assert( listListMonad.compose(listListMonad.compose(v,v),v)(0)
!= listListMonad.compose(v,listListMonad.compose(v,v)))
assert( listListMonad.compose(listListMonad.compose(v,v),v)(0)
== List(List(0,1,0,0,1),List(0,1,1,0,1),List(0,1,0,0),List(0,1,0,1),List(0,1,1,0),List(0,1,1,1)) )
assert( listListMonad.compose(v,listListMonad.compose(v,v))(0)
== List(List(0,1,0,0,1),List(0,1,0,0),List(0,1,0,1),List(0,1,1,0,1),List(0,1,1,0),List(0,1,1,1)) )

More Related Content

What's hot

Monoids - Part 2 - with examples using Scalaz and Cats
Monoids - Part 2 - with examples using Scalaz and CatsMonoids - Part 2 - with examples using Scalaz and Cats
Monoids - Part 2 - with examples using Scalaz and CatsPhilip Schwarz
 
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Philip 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
 
Scala collection methods flatMap and flatten are more powerful than monadic f...
Scala collection methods flatMap and flatten are more powerful than monadic f...Scala collection methods flatMap and flatten are more powerful than monadic f...
Scala collection methods flatMap and flatten are more powerful than monadic f...Philip Schwarz
 
Scala 3 enum for a terser Option Monad Algebraic Data Type
Scala 3 enum for a terser Option Monad Algebraic Data TypeScala 3 enum for a terser Option Monad Algebraic Data Type
Scala 3 enum for a terser Option Monad Algebraic Data TypePhilip Schwarz
 
Functional Core and Imperative Shell - Game of Life Example - Haskell and Scala
Functional Core and Imperative Shell - Game of Life Example - Haskell and ScalaFunctional Core and Imperative Shell - Game of Life Example - Haskell and Scala
Functional Core and Imperative Shell - Game of Life Example - Haskell and ScalaPhilip Schwarz
 
Simple IO Monad in 'Functional Programming in Scala'
Simple IO Monad in 'Functional Programming in Scala'Simple IO Monad in 'Functional Programming in Scala'
Simple IO Monad in 'Functional Programming in Scala'Philip Schwarz
 
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
 
Real World Haskell: Lecture 5
Real World Haskell: Lecture 5Real World Haskell: Lecture 5
Real World Haskell: Lecture 5Bryan O'Sullivan
 
Left and Right Folds - Comparison of a mathematical definition and a programm...
Left and Right Folds- Comparison of a mathematical definition and a programm...Left and Right Folds- Comparison of a mathematical definition and a programm...
Left and Right Folds - Comparison of a mathematical definition and a programm...Philip Schwarz
 
Real World Haskell: Lecture 4
Real World Haskell: Lecture 4Real World Haskell: Lecture 4
Real World Haskell: Lecture 4Bryan O'Sullivan
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Philip Schwarz
 
Linear Types in Haskell
Linear Types in HaskellLinear Types in Haskell
Linear Types in HaskellDavid Overton
 
Real World Haskell: Lecture 2
Real World Haskell: Lecture 2Real World Haskell: Lecture 2
Real World Haskell: Lecture 2Bryan O'Sullivan
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5Philip Schwarz
 
Fp in scala part 1
Fp in scala part 1Fp in scala part 1
Fp in scala part 1Hang Zhao
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...Philip Schwarz
 

What's hot (20)

Monoids - Part 2 - with examples using Scalaz and Cats
Monoids - Part 2 - with examples using Scalaz and CatsMonoids - Part 2 - with examples using Scalaz and Cats
Monoids - Part 2 - with examples using Scalaz and Cats
 
Functors
FunctorsFunctors
Functors
 
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
 
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
 
Monad Fact #2
Monad Fact #2Monad Fact #2
Monad Fact #2
 
Scala collection methods flatMap and flatten are more powerful than monadic f...
Scala collection methods flatMap and flatten are more powerful than monadic f...Scala collection methods flatMap and flatten are more powerful than monadic f...
Scala collection methods flatMap and flatten are more powerful than monadic f...
 
Scala 3 enum for a terser Option Monad Algebraic Data Type
Scala 3 enum for a terser Option Monad Algebraic Data TypeScala 3 enum for a terser Option Monad Algebraic Data Type
Scala 3 enum for a terser Option Monad Algebraic Data Type
 
Monad Fact #4
Monad Fact #4Monad Fact #4
Monad Fact #4
 
Functional Core and Imperative Shell - Game of Life Example - Haskell and Scala
Functional Core and Imperative Shell - Game of Life Example - Haskell and ScalaFunctional Core and Imperative Shell - Game of Life Example - Haskell and Scala
Functional Core and Imperative Shell - Game of Life Example - Haskell and Scala
 
Simple IO Monad in 'Functional Programming in Scala'
Simple IO Monad in 'Functional Programming in Scala'Simple IO Monad in 'Functional Programming in Scala'
Simple IO Monad in 'Functional Programming in Scala'
 
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...
 
Real World Haskell: Lecture 5
Real World Haskell: Lecture 5Real World Haskell: Lecture 5
Real World Haskell: Lecture 5
 
Left and Right Folds - Comparison of a mathematical definition and a programm...
Left and Right Folds- Comparison of a mathematical definition and a programm...Left and Right Folds- Comparison of a mathematical definition and a programm...
Left and Right Folds - Comparison of a mathematical definition and a programm...
 
Real World Haskell: Lecture 4
Real World Haskell: Lecture 4Real World Haskell: Lecture 4
Real World Haskell: Lecture 4
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
 
Linear Types in Haskell
Linear Types in HaskellLinear Types in Haskell
Linear Types in Haskell
 
Real World Haskell: Lecture 2
Real World Haskell: Lecture 2Real World Haskell: Lecture 2
Real World Haskell: Lecture 2
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 5
 
Fp in scala part 1
Fp in scala part 1Fp in scala part 1
Fp in scala part 1
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
 

Similar to 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...Philip Schwarz
 
Monad Laws Must be Checked
Monad Laws Must be CheckedMonad Laws Must be Checked
Monad Laws Must be CheckedPhilip Schwarz
 
Programming in Scala - Lecture Four
Programming in Scala - Lecture FourProgramming in Scala - Lecture Four
Programming in Scala - Lecture FourAngelo Corsaro
 
And now you have two problems. Ruby regular expressions for fun and profit by...
And now you have two problems. Ruby regular expressions for fun and profit by...And now you have two problems. Ruby regular expressions for fun and profit by...
And now you have two problems. Ruby regular expressions for fun and profit by...Codemotion
 
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
 
16 Java Regex
16 Java Regex16 Java Regex
16 Java Regexwayn
 
Introduction to Functional Languages
Introduction to Functional LanguagesIntroduction to Functional Languages
Introduction to Functional Languagessuthi
 
Unit 1-array,lists and hashes
Unit 1-array,lists and hashesUnit 1-array,lists and hashes
Unit 1-array,lists and hashessana mateen
 
List-based Monadic Computations for Dynamic Languages
List-based Monadic Computations for Dynamic LanguagesList-based Monadic Computations for Dynamic Languages
List-based Monadic Computations for Dynamic LanguagesWim Vanderbauwhede
 
Introduction to regular expressions
Introduction to regular expressionsIntroduction to regular expressions
Introduction to regular expressionsBen Brumfield
 
Why is Haskell so hard! (And how to deal with it?)
Why is Haskell so hard! (And how to deal with it?)Why is Haskell so hard! (And how to deal with it?)
Why is Haskell so hard! (And how to deal with it?)Saurabh Nanda
 
Programming in Scala - Lecture Three
Programming in Scala - Lecture ThreeProgramming in Scala - Lecture Three
Programming in Scala - Lecture ThreeAngelo Corsaro
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2Hang Zhao
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
Automatic Type Class Derivation with Shapeless
Automatic Type Class Derivation with ShapelessAutomatic Type Class Derivation with Shapeless
Automatic Type Class Derivation with Shapelessjcazevedo
 
mutable pairs_and_lists
mutable pairs_and_listsmutable pairs_and_lists
mutable pairs_and_listsRajendran
 

Similar to Addendum to ‘Monads do not Compose’ (20)

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...
 
Template Haskell
Template HaskellTemplate Haskell
Template Haskell
 
Monad Laws Must be Checked
Monad Laws Must be CheckedMonad Laws Must be Checked
Monad Laws Must be Checked
 
Programming in Scala - Lecture Four
Programming in Scala - Lecture FourProgramming in Scala - Lecture Four
Programming in Scala - Lecture Four
 
Bound
BoundBound
Bound
 
And now you have two problems. Ruby regular expressions for fun and profit by...
And now you have two problems. Ruby regular expressions for fun and profit by...And now you have two problems. Ruby regular expressions for fun and profit by...
And now you have two problems. Ruby regular expressions for fun and profit by...
 
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...
 
16 Java Regex
16 Java Regex16 Java Regex
16 Java Regex
 
Introduction to Functional Languages
Introduction to Functional LanguagesIntroduction to Functional Languages
Introduction to Functional Languages
 
Buacm 2
Buacm 2Buacm 2
Buacm 2
 
Unit 1-array,lists and hashes
Unit 1-array,lists and hashesUnit 1-array,lists and hashes
Unit 1-array,lists and hashes
 
List-based Monadic Computations for Dynamic Languages
List-based Monadic Computations for Dynamic LanguagesList-based Monadic Computations for Dynamic Languages
List-based Monadic Computations for Dynamic Languages
 
Practical cats
Practical catsPractical cats
Practical cats
 
Introduction to regular expressions
Introduction to regular expressionsIntroduction to regular expressions
Introduction to regular expressions
 
Why is Haskell so hard! (And how to deal with it?)
Why is Haskell so hard! (And how to deal with it?)Why is Haskell so hard! (And how to deal with it?)
Why is Haskell so hard! (And how to deal with it?)
 
Programming in Scala - Lecture Three
Programming in Scala - Lecture ThreeProgramming in Scala - Lecture Three
Programming in Scala - Lecture Three
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Automatic Type Class Derivation with Shapeless
Automatic Type Class Derivation with ShapelessAutomatic Type Class Derivation with Shapeless
Automatic Type Class Derivation with Shapeless
 
mutable pairs_and_lists
mutable pairs_and_listsmutable pairs_and_lists
mutable pairs_and_lists
 

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

Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
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
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
software engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxsoftware engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxnada99848
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
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
 
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
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
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
 
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
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 

Recently uploaded (20)

Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
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
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
software engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxsoftware engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptx
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
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...
 
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...
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
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
 
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
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
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
 

Addendum to ‘Monads do not Compose’

  • 1. Addendum to ‘Monads do not Compose’ a temporary addendum to Part 1 of ‘Monads do not Compose’ illustrating an issue raised by Sergei Winitzki @philip_schwarz https://www.slideshare.net/pjschwarz/monads-do-not-compose
  • 2. It is a mistake to think that a traversable monad can be composed with another monad. It is true that, given `Traversable`, you can implement the monad's methods (pure and flatMap) for the composition with another monad (as in your slides 21 to 26), but this is a deceptive appearance. The laws of the `Traversable` typeclass are far insufficient to guarantee the laws of the resulting composed monad. The only traversable monads that work correctly are Option, Either, and Writer. It is true that you can implement the type signature of the `swap` function for any `Traversable` monad. However, the `swap` function for monads needs to satisfy very different and stronger laws than the `sequence` function from the `Traversable` type class. I'll have to look at the "Book of Monads"; but, if my memory serves, the FPiS book does not derive any of these laws.Sergei Winitzki sergei-winitzki-11a6431 Thank you very much for taking the time to raise this concern. As seen in Part 1, the Book of Monads says “we definitely need a swap function if we want to combine two monads, but this is not enough. The reason is that a well-typed implementation may lead to a combined monad that violates one of the monad laws. The list monad is a well-known example of this.” So it looks like similar concerns apply when Traversable is used to provide the swap function. In FPiS there is no example of using composeM to automatically wrap a Traversable Monad in any other Monad, so in Part 1 I had a go and provided an example by composing the Option Monad with the Traversable List Monad. I need to check if the resulting Monad satisfies the Monad laws. In the meantime, see the next two slides for an example of the invalid composition of a Monad with a Traversable Monad. I compose the List Traversable Monad with itself and while in some cases the resulting Monad satisfies the monadic associative law, in another case (mentioned in the Book of Monads), it doesn’t. @philip_schwarz
  • 3. // sample A => F[B] function val f: String => List[String] = _.split(" ").toList.map(_.capitalize) assert(f("dog cat rabbit parrot") == List("Dog", "Cat", "Rabbit", "Parrot")) // sample B => F[C] function val g: String => List[Int] = _.toList.map(_.toInt) assert(g("Cat") == List(67, 97, 116)) // sample C => F[D] function val h: Int => List[Char] = _.toString.toList assert(h(102) == List('1', '0', '2')) // sample A value val a = "dog cat rabbit parrot" // sample B value val b = "Cat" // sample C value val c = 67 // sample D value val d = '6' // expected value of applying to "dog cat rabbit parrot" // the kleisli composition of f, g and h val expected = List( /* Dog */ '6', '8', '1', '1', '1', '1', '0', '3', /* Cat */ '6', '7', '9', '7', '1', '1', '6', /* Rabbit */ '8', '2', '9', '7', '9', '8', '9', '8', '1', '0', '5', '1', '1', '6', /* Parrot */ '8', '0', '9', '7', '1', '1', '4', '1', '1', '4', '1', '1', '1', '1', '1', '6') // monadic associative law: x.flatMap(f).flatMap(g) == x.flatMap(a => f(a).flatMap(g)) // alternative formuation using kleisli composition: compose(compose(f, g), h) == compose(f, compose(g, h)) // the traversable list monad satisfies the associative law because its kleisli composition is associative assert( traversableListMonad.compose(traversableListMonad.compose(f,g),h)("dog cat rabbit parrot") == expected) assert( traversableListMonad.compose(f,traversableListMonad.compose(g,h))("dog cat rabbit parrot") == expected) // Kleisli composition (defined on Monad F) def compose[A,B,C](f: A => F[B], g: B => F[C]): A => F[C] = { a => flatMap(f(a))(g) } // Monad composition def composeM[G[_],H[_]](implicit G: Monad[G], H: Monad[H], T: Traverse[H]): Monad[({type f[x] = G[H[x]]})#f] = new Monad[({type f[x] = G[H[x]]})#f] { def unit[A](a: => A): G[H[A]] = G.unit(H.unit(a)) override def flatMap[A,B](mna: G[H[A]])(f: A => G[H[B]]): G[H[B]] = { G.flatMap(mna)(na => G.map(T.traverse(na)(f))(H.join)) } } // Let's define a traversable List Monad val traversableListMonad = new Monad[List] with Traverse[List] { def unit[A](a: => A): List[A] = List(a) override def flatMap[A,B](ma: List[A])(f: A => List[B]): List[B] = ma flatMap f override def map[A,B](m: List[A])(f: A => B): List[B] = m map f override def join[A](mma: List[List[A]]): List[A] = mma.flatten override def traverse[M[_],A,B](as: List[A]) (f: A => M[B])(implicit M: Applicative[M]): M[List[B]] = { as.foldRight(M.unit(List[B]()))((a, fbs) => M.map2(f(a), fbs)(_ :: _)) } }
  • 4. // compose traversableListMonad with itself val listListMonad = composeM(traversableListMonad,traversableListMonad,traversableListMonad) // Now let’s tweak f, g, and h to return a List of a List rather than just a List, so that they are amenable to // composing using listListMonad’s kleisli composition, whose signature is // def compose[A,B,C](f: A => List[List[B]], g: B => List[List[C]]): A => List[List[C]] val ff: String => List[List[String]] = s => List(f(s),f(s)) val gg: String => List[List[Int]] = s => List(g(s),g(s)) val hh: Int => List[List[Char]] = n => List(h(n)) // listListMonad appears to satisfy the associative law assert( listListMonad.compose(listListMonad.compose(fff,ggg),hhh)("dog cat rabbit parrot") == List.fill(32)(expected)) assert( listListMonad.compose(fff,listListMonad.compose(ggg,hhh))("dog cat rabbit parrot") == List.fill(32)(expected)) // but it doesn't: here is an example (by Petr Pudlak) of a function for which kleisli composition is not associative def v(n: Int): List[List[Int]] = n match { case 0 => List(List(0,1)) case 1 => List(List(0),List(1)) } // listListMonad's kleisli composition is not associative when we compose function v with itself assert( listListMonad.compose(listListMonad.compose(v,v),v)(0) != listListMonad.compose(v,listListMonad.compose(v,v))) assert( listListMonad.compose(listListMonad.compose(v,v),v)(0) == List(List(0,1,0,0,1),List(0,1,1,0,1),List(0,1,0,0),List(0,1,0,1),List(0,1,1,0),List(0,1,1,1)) ) assert( listListMonad.compose(v,listListMonad.compose(v,v))(0) == List(List(0,1,0,0,1),List(0,1,0,0),List(0,1,0,1),List(0,1,1,0,1),List(0,1,1,0),List(0,1,1,1)) )