Nat, List and Option Monoids - from scratch - Combining and Folding - an example

Philip Schwarz
Philip SchwarzSoftware development is what I am passionate about
@philip_schwarz
slides by https://www.slideshare.net/pjschwarz
Nat, List and Option Monoids
from scratch
Combining and Folding
an example
enum Nat:
case Zero
case Succ(n: Nat)
𝐝𝐚𝐭𝐚 𝑵𝒂𝒕 = 𝒁𝒆𝒓𝒐 | 𝑺𝒖𝒄𝒄 𝑵𝒂𝒕
+ ∷ 𝑵𝒂𝒕 → 𝑵𝒂𝒕 → 𝑵𝒂𝒕
𝑚 + 𝒁𝒆𝒓𝒐 = 𝑚
𝑚 + 𝑺𝒖𝒄𝒄 𝑛 = 𝑺𝒖𝒄𝒄 𝑚 + 𝑛
(×) ∷ 𝑵𝒂𝒕 → 𝑵𝒂𝒕 → 𝑵𝒂𝒕
𝑚 × 𝒁𝒆𝒓𝒐 = 𝒁𝒆𝒓𝒐
𝑚 × 𝑺𝒖𝒄𝒄 𝑛 = 𝑚 × 𝑛 + 𝑚 extension (m: Nat)
def +(n: Nat): Nat = n match
case Zero => m
case Succ(n) => Succ(m + n)
def *(n: Nat): Nat = n match
case Zero => Zero
case Succ(n) => m * n + m
assert( zero + one == one )
assert( one + zero == one )
assert( one + two == three )
assert( one + two + three == six )
val zero = Zero
val one = Succ(zero)
val two = Succ(one)
val three = Succ(two)
val four = Succ(three)
val five = Succ(four)
val six = Succ(five)
assert( two * one == two )
assert( one * two == two )
assert( two * three == six )
assert( one * two * three == six )
trait Semigroup[A]:
def combine(x: A, y: A): A
object Semigroup:
extension [A](lhs: A)(using m: Semigroup[A])
def ⨁(rhs: A): A = m.combine(lhs,rhs)
given Monoid[Nat] with
def unit: Nat = Zero
def combine(x: Nat, y: Nat): Nat = x + y
trait Monoid[A] extends Semigroup[A]:
def unit: A
assert( summon[Monoid[Nat]].combine(two,three) == five )
assert( (two ⨁ three) == five )
assert( (one ⨁ two ⨁ three) == six )
val oneTwo = Cons(one,Cons(two,Nil))
val threeFour = Cons(three,Cons(four,Nil))
assert(append(oneTwo,threeFour) == Cons(one,Cons(two,Cons(three,Cons(four,Nil)))))
assert(oneTwo ++ threeFour == Cons(one,Cons(two,Cons(three,Cons(four,Nil)))))
enum List[+A]:
case Cons(head: A, tail: List[A])
case Nil
𝒅𝒂𝒕𝒂 𝑳𝒊𝒔𝒕 𝛼 = 𝑵𝒊𝒍 | 𝑪𝒐𝒏𝒔 𝛼 (𝑳𝒊𝒔𝒕 𝛼)
𝑪𝒐𝒏𝒔 1 (𝑪𝒐𝒏𝒔 2 (𝑪𝒐𝒏𝒔 3 𝑵𝒊𝒍 ))
object List:
def append[A](lhs: List[A], rhs: List[A]): List[A] = lhs match
case Nil => rhs
case Cons(a, rest) => Cons(a,append(rest,rhs))
extension [A](lhs: List[A])
def ++(rhs: List[A]): List[A] = append(lhs,rhs)
assert(List(one,two,three) == Cons(one,Cons(two,Cons(three,Nil))))
assert(List(one,two) ++ List(three, four) ++ Nil == List(one,two,three,four))
given ListMonoid[A]: Monoid[List[A]] with
def unit: List[A] = Nil
def combine(lhs: List[A], rhs: List[A]): List[A] = lhs ++ rhs
assert(summon[Monoid[List[Nat]]].combine(List(one,two),List(three, four)) == List(one,two,three,four))
assert((List(one,two) ⨁ List(three, four)) == List(one,two,three,four))
object List:
def apply[A](as: A*): List[A] = as match
case Seq() => Nil
case _ => Cons(as.head, List(as.tail*))
def append[A](lhs: List[A], rhs: List[A]): List[A] = lhs match
case Nil => rhs
case Cons(a, rest) => Cons(a,append(rest,rhs))
extension [A](lhs: List[A])
def ++(rhs: List[A]): List[A] = append(lhs,rhs)
object List:
def apply[A](as: A*): List[A] = as match
case Seq() => Nil
case _ => Cons(as.head, List(as.tail*))
def nil[A]: List[A] = Nil
def append[A](lhs: List[A], rhs: List[A]): List[A] = lhs match
case Nil => rhs
case Cons(a, rest) => Cons(a,append(rest,rhs))
extension [A](lhs: List[A])
def ++(rhs: List[A]): List[A] = append(lhs,rhs)
def fold[A](as: List[A])(using ma: Monoid[A]): A = as match
case Nil => ma.unit
case Cons(a,rest) => ma.combine(a,fold(rest))
assert(fold(List(one,two,three,four)) == one + two + three + four)
assert(fold(nil[Nat]) == zero)
assert(fold(List(List(one,two),Nil,List(three, four),List(five,six)))
== List(one,two,three,four,five,six))
object List:
def apply[A](as: A*): List[A] = as match
case Seq() => Nil
case _ => Cons(as.head, List(as.tail*))
def nil[A]: List[A] = Nil
def append[A](lhs: List[A], rhs: List[A]): List[A] = lhs match
case Nil => rhs
case Cons(a, rest) => Cons(a,append(rest,rhs))
extension [A](lhs: List[A])
def ++(rhs: List[A]): List[A] = append(lhs,rhs)
def fold[A](as: List[A])(using ma: Monoid[A]): A =
foldRight(as, ma.unit, (a,b) => ma.combine(a,b))
def foldRight[A,B](as: List[A], b: B, f: (A, B) => B): B = as match
case Nil => b
case Cons(a,rest) => f(a,foldRight(rest,b,f))
assert(fold(List(one,two,three,four)) == one + two + three + four)
assert(fold(nil[Nat]) == zero)
assert(fold(List(List(one,two),Nil,List(three, four),List(five,six)))
== List(one,two,three,four,five,six))
Same as the previous slide,
except that here we define
fold in terms of foldRight.
@philip_schwarz
val natMultMonoid = new Monoid[Nat]:
def unit: Nat = Succ(Zero)
def combine(x: Nat, y: Nat): Nat = x * y
assert(fold(List(one,two,three,four))(using natMultMonoid) == one * two * three * four)
assert(fold(nil[Nat])(using natMultMonoid) == one)
given OptionMonoid[A:Semigroup]: Monoid[Option[A]] with
def unit: Option[A] = None
def combine(ox: Option[A], oy: Option[A]): Option[A] = (ox,oy) match
case (None,_) => oy
case (_,None) => ox
case (Some(x),Some(y)) => Some(x ⨁ y)
enum Option[+A]:
case None
case Some(value:A)
object Option:
def none[A]: Option[A] = None
def some[A](a:A): Option[A] = Some(a)
assert((some(two) ⨁ None) == Some(two))
assert((none[Nat] ⨁ Some(two)) == Some(two))
assert((some(two) ⨁ Some(three)) == Some(five))
assert((none[Nat] ⨁ None) == None)
assert(summon[Monoid[Option[Nat]]].combine(Some(two),Some(three)) == Some(five))
assert(summon[Monoid[Option[Nat]]].combine(Some(two),None) == Some(two))
assert(summon[Monoid[Option[Nat]]].combine(none[Nat],Some(two)) == Some(two))
assert(summon[Monoid[Option[Nat]]].combine(none[Nat],None) == None)
𝒅𝒂𝒕𝒂 𝑴𝒂𝒚𝒃𝒆 𝛼 = 𝑵𝒐𝒕𝒉𝒊𝒏𝒈 | 𝑱𝒖𝒔𝒕 𝛼
assert(fold(List(Some(two),None,Some(three))) == Some(five))
assert(fold(nil[Option[Nat]]) == None)
assert((List(Some(one),None,Some(two)) ++ List(Some(three),None,Some(four)))
== List(Some(one),None,Some(two),Some(three),None,Some(four)))
assert(summon[Monoid[List[Option[Nat]]]].combine(List(Some(one),None,Some(two)),List(Some(three),None,Some(four)))
== List(Some(one),None,Some(two),Some(three),None,Some(four)))
assert((List(Some(one),None,Some(two)) ⨁ List(Some(three),None,Some(four)))
== List(Some(one),None,Some(two),Some(three),None,Some(four)))
assert(fold(List(Some(one),None,Some(two)) ⨁ List(Some(three),None,Some(four)))
== Some(one + two + three + four))
assert(
fold(
fold(
List(List(Some(one), None, Some(two)),
List(Some(three), None, Some(four)),
List(Some(five), None, Some(six)))
)
)
== Some(one + two + three + four + five + six))
assert((some(List(one,two)) ⨁ None ⨁ Some(List(three,four)))
== Some(List(one,two,three,four)))
That’s all.
I hope you found it useful.
@philip_schwarz
1 of 12

Recommended

Scala Left Fold Parallelisation - Three Approaches by
Scala Left Fold Parallelisation- Three ApproachesScala Left Fold Parallelisation- Three Approaches
Scala Left Fold Parallelisation - Three ApproachesPhilip Schwarz
41 views44 slides
Tagless Final Encoding - Algebras and Interpreters and also Programs by
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
45 views16 slides
Fusing Transformations of Strict Scala Collections with Views by
Fusing Transformations of Strict Scala Collections with ViewsFusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with ViewsPhilip Schwarz
20 views28 slides
A sighting of sequence function in Practical FP in Scala by
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
28 views4 slides
N-Queens Combinatorial Puzzle meets Cats by
N-Queens Combinatorial Puzzle meets CatsN-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets CatsPhilip Schwarz
33 views386 slides
Kleisli composition, flatMap, join, map, unit - implementation and interrelat... by
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
12 views16 slides

More Related Content

More from Philip Schwarz

Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha... by
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
827 views20 slides
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t... by
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
1.2K views46 slides
Jordan Peterson - The pursuit of meaning and related ethical axioms by
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
141 views12 slides
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c... by
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
100 views1 slide
Defining filter using (a) recursion (b) folding with S, B and I combinators (... by
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
78 views1 slide
The Sieve of Eratosthenes - Part 1 - with minor corrections by
The Sieve of Eratosthenes - Part 1 - with minor correctionsThe Sieve of Eratosthenes - Part 1 - with minor corrections
The Sieve of Eratosthenes - Part 1 - with minor correctionsPhilip Schwarz
110 views50 slides

More from Philip Schwarz(20)

Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha... by 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...
Philip Schwarz827 views
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t... by Philip Schwarz
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 Schwarz1.2K views
Jordan Peterson - The pursuit of meaning and related ethical axioms by Philip Schwarz
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
Philip Schwarz141 views
Defining filter using (a) recursion (b) folding (c) folding with S, B and I c... by Philip 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...
Philip Schwarz100 views
Defining filter using (a) recursion (b) folding with S, B and I combinators (... by 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 (...
Philip Schwarz78 views
The Sieve of Eratosthenes - Part 1 - with minor corrections by Philip Schwarz
The Sieve of Eratosthenes - Part 1 - with minor correctionsThe Sieve of Eratosthenes - Part 1 - with minor corrections
The Sieve of Eratosthenes - Part 1 - with minor corrections
Philip Schwarz110 views
The Sieve of Eratosthenes - Part 1 by Philip Schwarz
The Sieve of Eratosthenes - Part 1The Sieve of Eratosthenes - Part 1
The Sieve of Eratosthenes - Part 1
Philip Schwarz1K views
The Uniform Access Principle by Philip Schwarz
The Uniform Access PrincipleThe Uniform Access Principle
The Uniform Access Principle
Philip Schwarz542 views
Computer Graphics in Java and Scala - Part 1b by Philip Schwarz
Computer Graphics in Java and Scala - Part 1bComputer Graphics in Java and Scala - Part 1b
Computer Graphics in Java and Scala - Part 1b
Philip Schwarz261 views
The Expression Problem - Part 2 by Philip Schwarz
The Expression Problem - Part 2The Expression Problem - Part 2
The Expression Problem - Part 2
Philip Schwarz650 views
Computer Graphics in Java and Scala - Part 1 by Philip Schwarz
Computer Graphics in Java and Scala - Part 1Computer Graphics in Java and Scala - Part 1
Computer Graphics in Java and Scala - Part 1
Philip Schwarz403 views
The Expression Problem - Part 1 by Philip Schwarz
The Expression Problem - Part 1The Expression Problem - Part 1
The Expression Problem - Part 1
Philip Schwarz1.2K views
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac... by Philip Schwarz
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...
Philip Schwarz268 views
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ... by Philip Schwarz
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
Philip Schwarz312 views
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ... by Philip Schwarz
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
Refactoring: A First Example - Martin Fowler’s First Example of Refactoring, ...
Philip Schwarz630 views
‘go-to’ general-purpose sequential collections - from Java To Scala by Philip Schwarz
‘go-to’ general-purpose sequential collections -from Java To Scala‘go-to’ general-purpose sequential collections -from Java To Scala
‘go-to’ general-purpose sequential collections - from Java To Scala
Philip Schwarz767 views
The Functional Programming Triad of Map, Filter and Fold by Philip Schwarz
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and Fold
Philip Schwarz3.5K views
Functional Core and Imperative Shell - Game of Life Example - Haskell and Scala by Philip Schwarz
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
Philip Schwarz825 views
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit - Haskell and... by 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...
Philip Schwarz495 views
Quicksort - a whistle-stop tour of the algorithm in five languages and four p... by Philip 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...
Philip Schwarz1.2K views

Recently uploaded

BushraDBR: An Automatic Approach to Retrieving Duplicate Bug Reports by
BushraDBR: An Automatic Approach to Retrieving Duplicate Bug ReportsBushraDBR: An Automatic Approach to Retrieving Duplicate Bug Reports
BushraDBR: An Automatic Approach to Retrieving Duplicate Bug ReportsRa'Fat Al-Msie'deen
8 views49 slides
DSD-INT 2023 Thermobaricity in 3D DCSM-FM - taking pressure into account in t... by
DSD-INT 2023 Thermobaricity in 3D DCSM-FM - taking pressure into account in t...DSD-INT 2023 Thermobaricity in 3D DCSM-FM - taking pressure into account in t...
DSD-INT 2023 Thermobaricity in 3D DCSM-FM - taking pressure into account in t...Deltares
9 views26 slides
DSD-INT 2023 3D hydrodynamic modelling of microplastic transport in lakes - J... by
DSD-INT 2023 3D hydrodynamic modelling of microplastic transport in lakes - J...DSD-INT 2023 3D hydrodynamic modelling of microplastic transport in lakes - J...
DSD-INT 2023 3D hydrodynamic modelling of microplastic transport in lakes - J...Deltares
9 views24 slides
SAP FOR TYRE INDUSTRY.pdf by
SAP FOR TYRE INDUSTRY.pdfSAP FOR TYRE INDUSTRY.pdf
SAP FOR TYRE INDUSTRY.pdfVirendra Rai, PMP
24 views3 slides
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium... by
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...Lisi Hocke
30 views124 slides
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with... by
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...sparkfabrik
5 views46 slides

Recently uploaded(20)

BushraDBR: An Automatic Approach to Retrieving Duplicate Bug Reports by Ra'Fat Al-Msie'deen
BushraDBR: An Automatic Approach to Retrieving Duplicate Bug ReportsBushraDBR: An Automatic Approach to Retrieving Duplicate Bug Reports
BushraDBR: An Automatic Approach to Retrieving Duplicate Bug Reports
DSD-INT 2023 Thermobaricity in 3D DCSM-FM - taking pressure into account in t... by Deltares
DSD-INT 2023 Thermobaricity in 3D DCSM-FM - taking pressure into account in t...DSD-INT 2023 Thermobaricity in 3D DCSM-FM - taking pressure into account in t...
DSD-INT 2023 Thermobaricity in 3D DCSM-FM - taking pressure into account in t...
Deltares9 views
DSD-INT 2023 3D hydrodynamic modelling of microplastic transport in lakes - J... by Deltares
DSD-INT 2023 3D hydrodynamic modelling of microplastic transport in lakes - J...DSD-INT 2023 3D hydrodynamic modelling of microplastic transport in lakes - J...
DSD-INT 2023 3D hydrodynamic modelling of microplastic transport in lakes - J...
Deltares9 views
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium... by Lisi Hocke
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...
Lisi Hocke30 views
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with... by sparkfabrik
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...
sparkfabrik5 views
DSD-INT 2023 Simulating a falling apron in Delft3D 4 - Engineering Practice -... by Deltares
DSD-INT 2023 Simulating a falling apron in Delft3D 4 - Engineering Practice -...DSD-INT 2023 Simulating a falling apron in Delft3D 4 - Engineering Practice -...
DSD-INT 2023 Simulating a falling apron in Delft3D 4 - Engineering Practice -...
Deltares6 views
DSD-INT 2023 Salt intrusion Modelling of the Lauwersmeer, towards a measureme... by Deltares
DSD-INT 2023 Salt intrusion Modelling of the Lauwersmeer, towards a measureme...DSD-INT 2023 Salt intrusion Modelling of the Lauwersmeer, towards a measureme...
DSD-INT 2023 Salt intrusion Modelling of the Lauwersmeer, towards a measureme...
Deltares5 views
DSD-INT 2023 Wave-Current Interaction at Montrose Tidal Inlet System and Its ... by Deltares
DSD-INT 2023 Wave-Current Interaction at Montrose Tidal Inlet System and Its ...DSD-INT 2023 Wave-Current Interaction at Montrose Tidal Inlet System and Its ...
DSD-INT 2023 Wave-Current Interaction at Montrose Tidal Inlet System and Its ...
Deltares11 views
FIMA 2023 Neo4j & FS - Entity Resolution.pptx by Neo4j
FIMA 2023 Neo4j & FS - Entity Resolution.pptxFIMA 2023 Neo4j & FS - Entity Resolution.pptx
FIMA 2023 Neo4j & FS - Entity Resolution.pptx
Neo4j7 views
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra... by Marc Müller
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra....NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra...
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra...
Marc Müller38 views
Dev-HRE-Ops - Addressing the _Last Mile DevOps Challenge_ in Highly Regulated... by TomHalpin9
Dev-HRE-Ops - Addressing the _Last Mile DevOps Challenge_ in Highly Regulated...Dev-HRE-Ops - Addressing the _Last Mile DevOps Challenge_ in Highly Regulated...
Dev-HRE-Ops - Addressing the _Last Mile DevOps Challenge_ in Highly Regulated...
TomHalpin96 views
Fleet Management Software in India by Fleetable
Fleet Management Software in India Fleet Management Software in India
Fleet Management Software in India
Fleetable11 views
SUGCON ANZ Presentation V2.1 Final.pptx by Jack Spektor
SUGCON ANZ Presentation V2.1 Final.pptxSUGCON ANZ Presentation V2.1 Final.pptx
SUGCON ANZ Presentation V2.1 Final.pptx
Jack Spektor22 views
Generic or specific? Making sensible software design decisions by Bert Jan Schrijver
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisions
Dapr Unleashed: Accelerating Microservice Development by Miroslav Janeski
Dapr Unleashed: Accelerating Microservice DevelopmentDapr Unleashed: Accelerating Microservice Development
Dapr Unleashed: Accelerating Microservice Development
Miroslav Janeski10 views
Myths and Facts About Hospice Care: Busting Common Misconceptions by Care Coordinations
Myths and Facts About Hospice Care: Busting Common MisconceptionsMyths and Facts About Hospice Care: Busting Common Misconceptions
Myths and Facts About Hospice Care: Busting Common Misconceptions

Nat, List and Option Monoids - from scratch - Combining and Folding - an example

  • 1. @philip_schwarz slides by https://www.slideshare.net/pjschwarz Nat, List and Option Monoids from scratch Combining and Folding an example
  • 2. enum Nat: case Zero case Succ(n: Nat) 𝐝𝐚𝐭𝐚 𝑵𝒂𝒕 = 𝒁𝒆𝒓𝒐 | 𝑺𝒖𝒄𝒄 𝑵𝒂𝒕 + ∷ 𝑵𝒂𝒕 → 𝑵𝒂𝒕 → 𝑵𝒂𝒕 𝑚 + 𝒁𝒆𝒓𝒐 = 𝑚 𝑚 + 𝑺𝒖𝒄𝒄 𝑛 = 𝑺𝒖𝒄𝒄 𝑚 + 𝑛 (×) ∷ 𝑵𝒂𝒕 → 𝑵𝒂𝒕 → 𝑵𝒂𝒕 𝑚 × 𝒁𝒆𝒓𝒐 = 𝒁𝒆𝒓𝒐 𝑚 × 𝑺𝒖𝒄𝒄 𝑛 = 𝑚 × 𝑛 + 𝑚 extension (m: Nat) def +(n: Nat): Nat = n match case Zero => m case Succ(n) => Succ(m + n) def *(n: Nat): Nat = n match case Zero => Zero case Succ(n) => m * n + m assert( zero + one == one ) assert( one + zero == one ) assert( one + two == three ) assert( one + two + three == six ) val zero = Zero val one = Succ(zero) val two = Succ(one) val three = Succ(two) val four = Succ(three) val five = Succ(four) val six = Succ(five) assert( two * one == two ) assert( one * two == two ) assert( two * three == six ) assert( one * two * three == six )
  • 3. trait Semigroup[A]: def combine(x: A, y: A): A object Semigroup: extension [A](lhs: A)(using m: Semigroup[A]) def ⨁(rhs: A): A = m.combine(lhs,rhs) given Monoid[Nat] with def unit: Nat = Zero def combine(x: Nat, y: Nat): Nat = x + y trait Monoid[A] extends Semigroup[A]: def unit: A assert( summon[Monoid[Nat]].combine(two,three) == five ) assert( (two ⨁ three) == five ) assert( (one ⨁ two ⨁ three) == six )
  • 4. val oneTwo = Cons(one,Cons(two,Nil)) val threeFour = Cons(three,Cons(four,Nil)) assert(append(oneTwo,threeFour) == Cons(one,Cons(two,Cons(three,Cons(four,Nil))))) assert(oneTwo ++ threeFour == Cons(one,Cons(two,Cons(three,Cons(four,Nil))))) enum List[+A]: case Cons(head: A, tail: List[A]) case Nil 𝒅𝒂𝒕𝒂 𝑳𝒊𝒔𝒕 𝛼 = 𝑵𝒊𝒍 | 𝑪𝒐𝒏𝒔 𝛼 (𝑳𝒊𝒔𝒕 𝛼) 𝑪𝒐𝒏𝒔 1 (𝑪𝒐𝒏𝒔 2 (𝑪𝒐𝒏𝒔 3 𝑵𝒊𝒍 )) object List: def append[A](lhs: List[A], rhs: List[A]): List[A] = lhs match case Nil => rhs case Cons(a, rest) => Cons(a,append(rest,rhs)) extension [A](lhs: List[A]) def ++(rhs: List[A]): List[A] = append(lhs,rhs)
  • 5. assert(List(one,two,three) == Cons(one,Cons(two,Cons(three,Nil)))) assert(List(one,two) ++ List(three, four) ++ Nil == List(one,two,three,four)) given ListMonoid[A]: Monoid[List[A]] with def unit: List[A] = Nil def combine(lhs: List[A], rhs: List[A]): List[A] = lhs ++ rhs assert(summon[Monoid[List[Nat]]].combine(List(one,two),List(three, four)) == List(one,two,three,four)) assert((List(one,two) ⨁ List(three, four)) == List(one,two,three,four)) object List: def apply[A](as: A*): List[A] = as match case Seq() => Nil case _ => Cons(as.head, List(as.tail*)) def append[A](lhs: List[A], rhs: List[A]): List[A] = lhs match case Nil => rhs case Cons(a, rest) => Cons(a,append(rest,rhs)) extension [A](lhs: List[A]) def ++(rhs: List[A]): List[A] = append(lhs,rhs)
  • 6. object List: def apply[A](as: A*): List[A] = as match case Seq() => Nil case _ => Cons(as.head, List(as.tail*)) def nil[A]: List[A] = Nil def append[A](lhs: List[A], rhs: List[A]): List[A] = lhs match case Nil => rhs case Cons(a, rest) => Cons(a,append(rest,rhs)) extension [A](lhs: List[A]) def ++(rhs: List[A]): List[A] = append(lhs,rhs) def fold[A](as: List[A])(using ma: Monoid[A]): A = as match case Nil => ma.unit case Cons(a,rest) => ma.combine(a,fold(rest)) assert(fold(List(one,two,three,four)) == one + two + three + four) assert(fold(nil[Nat]) == zero) assert(fold(List(List(one,two),Nil,List(three, four),List(five,six))) == List(one,two,three,four,five,six))
  • 7. object List: def apply[A](as: A*): List[A] = as match case Seq() => Nil case _ => Cons(as.head, List(as.tail*)) def nil[A]: List[A] = Nil def append[A](lhs: List[A], rhs: List[A]): List[A] = lhs match case Nil => rhs case Cons(a, rest) => Cons(a,append(rest,rhs)) extension [A](lhs: List[A]) def ++(rhs: List[A]): List[A] = append(lhs,rhs) def fold[A](as: List[A])(using ma: Monoid[A]): A = foldRight(as, ma.unit, (a,b) => ma.combine(a,b)) def foldRight[A,B](as: List[A], b: B, f: (A, B) => B): B = as match case Nil => b case Cons(a,rest) => f(a,foldRight(rest,b,f)) assert(fold(List(one,two,three,four)) == one + two + three + four) assert(fold(nil[Nat]) == zero) assert(fold(List(List(one,two),Nil,List(three, four),List(five,six))) == List(one,two,three,four,five,six)) Same as the previous slide, except that here we define fold in terms of foldRight. @philip_schwarz
  • 8. val natMultMonoid = new Monoid[Nat]: def unit: Nat = Succ(Zero) def combine(x: Nat, y: Nat): Nat = x * y assert(fold(List(one,two,three,four))(using natMultMonoid) == one * two * three * four) assert(fold(nil[Nat])(using natMultMonoid) == one)
  • 9. given OptionMonoid[A:Semigroup]: Monoid[Option[A]] with def unit: Option[A] = None def combine(ox: Option[A], oy: Option[A]): Option[A] = (ox,oy) match case (None,_) => oy case (_,None) => ox case (Some(x),Some(y)) => Some(x ⨁ y) enum Option[+A]: case None case Some(value:A) object Option: def none[A]: Option[A] = None def some[A](a:A): Option[A] = Some(a) assert((some(two) ⨁ None) == Some(two)) assert((none[Nat] ⨁ Some(two)) == Some(two)) assert((some(two) ⨁ Some(three)) == Some(five)) assert((none[Nat] ⨁ None) == None) assert(summon[Monoid[Option[Nat]]].combine(Some(two),Some(three)) == Some(five)) assert(summon[Monoid[Option[Nat]]].combine(Some(two),None) == Some(two)) assert(summon[Monoid[Option[Nat]]].combine(none[Nat],Some(two)) == Some(two)) assert(summon[Monoid[Option[Nat]]].combine(none[Nat],None) == None) 𝒅𝒂𝒕𝒂 𝑴𝒂𝒚𝒃𝒆 𝛼 = 𝑵𝒐𝒕𝒉𝒊𝒏𝒈 | 𝑱𝒖𝒔𝒕 𝛼
  • 10. assert(fold(List(Some(two),None,Some(three))) == Some(five)) assert(fold(nil[Option[Nat]]) == None) assert((List(Some(one),None,Some(two)) ++ List(Some(three),None,Some(four))) == List(Some(one),None,Some(two),Some(three),None,Some(four))) assert(summon[Monoid[List[Option[Nat]]]].combine(List(Some(one),None,Some(two)),List(Some(three),None,Some(four))) == List(Some(one),None,Some(two),Some(three),None,Some(four))) assert((List(Some(one),None,Some(two)) ⨁ List(Some(three),None,Some(four))) == List(Some(one),None,Some(two),Some(three),None,Some(four))) assert(fold(List(Some(one),None,Some(two)) ⨁ List(Some(three),None,Some(four))) == Some(one + two + three + four))
  • 11. assert( fold( fold( List(List(Some(one), None, Some(two)), List(Some(three), None, Some(four)), List(Some(five), None, Some(six))) ) ) == Some(one + two + three + four + five + six)) assert((some(List(one,two)) ⨁ None ⨁ Some(List(three,four))) == Some(List(one,two,three,four)))
  • 12. That’s all. I hope you found it useful. @philip_schwarz