will it blend? - scalasyd february 2015
TRANSCRIPT
![Page 1: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/1.jpg)
Will it Blend?
February 2015
@filippovitale
![Page 2: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/2.jpg)
![Page 3: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/3.jpg)
valuevalue
value
Map Set
key value
key value
key value
Listv v v v
![Page 4: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/4.jpg)
List
![Page 5: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/5.jpg)
Immutable Collection Hierarchy
Traversable Seq List
http://docs.scala-lang.org/tutorials/FAQ/collections.html
![Page 6: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/6.jpg)
Immutable Collection Hierarchy
Traversable Seq List
http://docs.scala-lang.org/tutorials/FAQ/collections.html
def ++[B] (that:Traversable[B])
:Traversable[B]
![Page 7: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/7.jpg)
Blending Lists
List(1, 2, 3) ++ List(4, 5, 6) == ???
![Page 8: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/8.jpg)
Blending Appending Lists
List(1, 2, 3) ++ List(4, 5, 6) == List(1, 2, 3, 4, 5, 6)
http://www.scala-lang.org/api/current/#scala.collection.immutable.List
http://docs.scala-lang.org/overviews/collections/seqs.html
def ++[B](that: Traversable[B]): List[B]
Returns a new list containing the elements from the left hand operand followed by the elements from the right hand operand.
![Page 9: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/9.jpg)
Set
![Page 10: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/10.jpg)
Immutable Collection Hierarchy
Traversable Seq
Set
List
HashSet
http://docs.scala-lang.org/tutorials/FAQ/collections.html
![Page 11: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/11.jpg)
Blending Sets
Set(1, 2, 3) ++ Set(4, 5, 6) == ???
![Page 12: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/12.jpg)
Blending Adding Sets
Set(1, 2, 3) ++ Set(4, 5, 6) == Set(5, 1, 6, 2, 3, 4)
http://www.scala-lang.org/api/current/#scala.collection.immutable.Set
http://docs.scala-lang.org/overviews/collections/sets.html
def ++[B](that: Traversable[B]): Set[B]
Returns a new set containing the elements from the left hand operand followed by the elements from the right hand operand.
![Page 13: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/13.jpg)
Blending Adding Sets
Set(1, 2, 3) ++ Set(4, 5, 6) == Set(5, 1, 6, 2, 3, 4)
Set(1, 2) ++ Set(2, 3) == Set(1, 2, 3)
![Page 14: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/14.jpg)
![Page 15: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/15.jpg)
![Page 16: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/16.jpg)
Map
![Page 17: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/17.jpg)
Immutable Collection Hierarchy
Traversable Seq
Set
Map
List
HashSet
HashMap
http://docs.scala-lang.org/tutorials/FAQ/collections.html
![Page 18: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/18.jpg)
Blending Adding Maps
Map() ++ Map("a" -> 1) == Map("a" -> 1)
http://www.scala-lang.org/api/current/#scala.collection.immutable.Map
http://docs.scala-lang.org/overviews/collections/maps.html
def ++[B](that: Traversable[(A, B)]): Map[A, B]
Returns a new map containing the elements from the left hand operand followed by the elements from the right hand operand.
![Page 19: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/19.jpg)
Blending Adding Maps
Map("a" -> Set(1, 2)) ++ Map("a" -> Set(2, 3)) == ???
http://www.scala-lang.org/api/current/#scala.collection.immutable.Map
http://docs.scala-lang.org/overviews/collections/maps.html
def ++[B](that: Traversable[(A, B)]): Map[A, B]
Returns a new map containing the elements from the left hand operand followed by the elements from the right hand operand.
![Page 20: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/20.jpg)
Map("a" -> Set(1, 2)) ++ Map("a" -> Set(2, 3)) == ???
1: Map("a" -> Set(1, 2))
2: Map("a" -> Set(1, 2, 3))
3: Map("a" -> Set(2, 3))
4: RuntimeException
5: Compiler Error
What is the result of “blending” those Maps?
![Page 21: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/21.jpg)
Map("a" -> Set(1, 2)) ++ Map("a" -> Set(2, 3)) == ???
1:
2:
3: Map("a" -> Set(2, 3))
4:
5:
What is the result of “blending” those Maps?
![Page 22: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/22.jpg)
Map("a" -> Set(1, 2)) ??? Map("a" -> Set(2, 3))
Map("a" -> Set(1, 2, 3))
![Page 23: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/23.jpg)
![Page 24: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/24.jpg)
![Page 25: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/25.jpg)
![Page 26: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/26.jpg)
Map with values as Set (of Int)
“a” Set(1, 2)
“key b” Set(4, 7, 5)
“key c” Set(9, 4)
“a” Set(2, 3)
“key c” Set(3, 4)
“key d” Set(5, 6)
val ma: Map[String, Set[Int]]
val mb: Map[String, Set[Int]]
![Page 27: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/27.jpg)
Map with values as Set (of Int)
“a” Set(1, 2) “a” Set(2, 3)
“a” Set(1, 2) ++ Set(2, 3)
![Page 28: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/28.jpg)
Map with values as Set (of Int)
“a” Set(1, 2) “a” Set(2, 3)
“a” Set(1, 2, 3)
![Page 29: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/29.jpg)
def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = { for ((k, v) <- mb) { ??? } }
![Page 30: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/30.jpg)
def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = { val result = mutable.Map() ++ ma for ((k, v) <- mb) { ??? } result.toMap}
![Page 31: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/31.jpg)
def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = { val result = mutable.Map() ++ ma mb foreach { case (k, v) => ??? } result.toMap}
![Page 32: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/32.jpg)
def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = { val result = mutable.Map() ++ ma mb foreach { case (k, v) => if (result.contains(k)) result += k -> (result(k) ++ v) else result += k -> v } result.toMap}
![Page 33: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/33.jpg)
def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = {
}
(ma /: mb) { case (result,(k, v)) => if (result.contains(k)) result + (k -> (result(k) ++ v)) else result + (k -> v)}
val result = mutable.Map() ++ mamb foreach { case (k, v) => if (result.contains(k)) result += k -> (result(k) ++ v) else result += k -> v}result.toMap
![Page 34: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/34.jpg)
def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = {
}
(ma /: mb) { case (result,(k, v)) => if (result.contains(k)) result + (k -> (result(k) ++ v)) else result + (k -> v)}
val result = mutable.Map() ++ mamb foreach { case (k, v) => if (result.contains(k)) result += k -> (result(k) ++ v) else result += k -> v}result.toMap
mb.foldLeft(ma) { ... }
![Page 35: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/35.jpg)
def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = {
}
(ma /: mb) { case (result,(k, v)) => if (result.contains(k)) result + (k -> (result(k) ++ v)) else result + (k -> v)}
val result = mutable.Map() ++ mamb foreach { case (k, v) => if (result.contains(k)) result += k -> (result(k) ++ v) else result += k -> v}result.toMap
![Page 36: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/36.jpg)
def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = {
}
(ma /: mb) { case (result,(k, v)) => if (result.contains(k)) result + (k -> (result(k) ++ v)) else result + (k -> v)}
val result = mutable.Map() ++ mamb foreach { case (k, v) => if (result.contains(k)) result += k -> (result(k) ++ v) else result += k -> v}result.toMap
![Page 37: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/37.jpg)
def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = { (ma /: mb) { case (result,(k, v)) => if (result.contains(k)) result + (k -> (result(k) ++ v)) else result + (k -> v) }}
![Page 38: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/38.jpg)
(ma /: mb) { case (result,(k, v)) =>result + (k -> { result.get(k) match { case Some(vr) => vr ++ v case None => v }}
![Page 39: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/39.jpg)
(ma /: mb) { case (result,(k, v)) =>result + (k -> { result.get(k) match { case Some(vr) => vr ++ v case None => v } // .map(_ ++ v).getOrElse(v) // // // }}
![Page 40: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/40.jpg)
(ma /: mb) { case (result,(k, v)) =>result + (k -> { result.get(k) match { case Some(vr) => vr ++ v case None => v } // .map(_ ++ v).getOrElse(v) // .some(_ ++ v).none(v) // // }}
![Page 41: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/41.jpg)
(ma /: mb) { case (result,(k, v)) =>result + (k -> { result.get(k) match { case Some(vr) => vr ++ v case None => v } // .map(_ ++ v).getOrElse(v) // .some(_ ++ v).none(v) // .fold(v)(_ ++ v) // }}
![Page 42: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/42.jpg)
(ma /: mb) { case (result,(k, v)) =>result + (k -> { result.get(k) match { case Some(vr) => vr ++ v case None => v } // .map(_ ++ v).getOrElse(v) // .some(_ ++ v).none(v) // .fold(v)(_ ++ v) // .cata(_ ++ v, v)}}
![Page 43: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/43.jpg)
(ma /: mb) { case (result,(k, v)) =>result + (k -> { result.get(k) match { case Some(vr) => vr ++ v case None => v } // .map(_ ++ v).getOrElse(v) // .some(_ ++ v).none(v) // .fold(v)(_ ++ v) // .cata(_ ++ v, v)}}
http://stackoverflow.com/questions/5328007/why-doesnt-option-have-a-fold-method
http://en.wikipedia.org/wiki/Catamorphism
“Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire”
![Page 44: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/44.jpg)
(ma /: mb) { case (result,(k, v)) =>result + (k -> { result.get(k) match { case Some(vr) => vr ++ v case None => v } // .map(_ ++ v).getOrElse(v) // .some(_ ++ v).none(v) // .fold(v)(_ ++ v) // .cata(_ ++ v, v)}}
http://stackoverflow.com/questions/5328007/why-doesnt-option-have-a-fold-method
http://en.wikipedia.org/wiki/Catamorphism
“Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire”
![Page 45: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/45.jpg)
(ma /: mb) { case (result, (k, v)) => result + (k -> result.get(k).cata(_ ++ v, v))}
val result = mutable.Map() ++ mamb foreach { case (k, v) => result += (k -> result.get(k).cata(_ ++ v, v))}
![Page 46: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/46.jpg)
![Page 47: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/47.jpg)
![Page 48: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/48.jpg)
![Page 49: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/49.jpg)
What if we changeData Structure?
![Page 50: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/50.jpg)
def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = (ma /: mb) { case (result, (k, v)) => result + (k -> result.get(k).cata(_ ++ v, v)) }
Map[String, Set[Int]] Map[String, Map[Int, Set[Int]]]
![Page 51: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/51.jpg)
def blend(ma: Map[String, Map[Int, Set[Int]]], mb: Map[String, Map[Int, Set[Int]]]): Map[String, Map[Int, Set[Int]]] = (ma /: mb) { case (result, (k, v)) => result + ??? // { ??? => { ??? } } }
Map[String, Set[Int]] Map[String, Map[Int, Set[Int]]]
![Page 52: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/52.jpg)
trait Blendable[A] { def blend(ma: A, mb: A): A}
new Blendable[...] { def blend(ma: ..., mb: ...): ... = ???}
![Page 53: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/53.jpg)
trait Blendable[A] { def blend(ma: A, mb: A): A}
new Blendable[...] { def blend(ma: ..., mb: ...): ... = ???}
x10 Developer
![Page 54: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/54.jpg)
What is the meaning of “Blending”?
(in my world)
![Page 55: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/55.jpg)
What blended “as expected”?
List using the ++ binary operator
Set using the ++ binary operator
List(1, 2, 3) ++ List(4, 5, 6) == List(1, 2, 3, 4, 5, 6)
Set(1, 2) ++ Set(2, 3) == Set(1, 2, 3)
![Page 56: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/56.jpg)
(List, ++)(Set, ++)
(1 blend 2) == ???
What about Int?
![Page 57: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/57.jpg)
(List, ++)(Set, ++)
(Int, +)
(1 blend 2) == 1 + 2 == 3
What about Int?
![Page 58: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/58.jpg)
(List, ++)(Set, ++)
(Int, +)(String, +)("ab" blend "cd") == ("ab" + "cd") == "abcd"
String
![Page 59: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/59.jpg)
(List, ++)(Set, ++)
(Int, +)(String, +)
(Map[...], Blendable[...].blend)
Blendable[Map[String, Set[Int]]].blend(ma, mb)
Map[String, Set[Int]]
![Page 60: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/60.jpg)
What canMathematicians
tell us here?
![Page 61: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/61.jpg)
Warning
Category Theory ahead
☣
![Page 62: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/62.jpg)
What is a Semigroup?
Michael Barr, Charles Wells - Category Theory for Computing Science
Semigroups
“A semigroup is a set S together with an associative binary operation m: S × S → S”
![Page 63: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/63.jpg)
Closure Property
http://en.wikipedia.org/wiki/Closure_(mathematics)
trait Semigroup[T] { def op(a: T, b: T): T}
For all a, b in T, the result of the operation a ⋅ b is also in T:
∀a, b ∈ T : a∙b ∈ T
![Page 64: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/64.jpg)
http://en.wikipedia.org/wiki/Closure_(mathematics)
trait Semigroup[T] { def op(a: T, b: T): T}
def op(a: Boolean, b: Boolean): Boolean
def op(a: Int, b: Int): Boolean
✓
✘
Closure Property
![Page 65: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/65.jpg)
Associative Property
http://en.wikipedia.org/wiki/Associative_property
trait Semigroup[T] { def op(a: T, b: T): T}
For all a, b, and c in T, the equation (a ⋅ b) ⋅ c = a ⋅ (b ⋅ c) holds:
∀a, b, c ∈ T : (a∙b)∙c = a∙(b∙c)
(a op b) op c==
a op (b op c)
![Page 66: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/66.jpg)
What is a Semigroup?
Michael Barr, Charles Wells - Category Theory for Computing Science
Semigroups
“A semigroup is a set S together with an associative binary operation m: S × S → S”
![Page 67: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/67.jpg)
Scalaz and Semigroup
![Page 68: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/68.jpg)
Scalaz and Semigroup
import scalaz.std.set._
![Page 69: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/69.jpg)
Scalaz and Semigroup implicit def setSemigroup[A]:Semigroup[Set[A]] =
new Semigroup[Set[A]] { def append(f1: Set[A], f2: => Set[A]) = f1 ++ f2 }
![Page 70: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/70.jpg)
Scalaz and Semigroup implicit def setSemigroup[A]:Semigroup[Set[A]] =
new Semigroup[Set[A]] { def append(f1: Set[A], f2: => Set[A]) = f1 ++ f2 }
op
![Page 71: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/71.jpg)
Scalaz and Semigroup import scalaz.syntax.semigroup._
import scalaz.std.list._
Set(1, 2) |+| Set(2, 3)
res0: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
![Page 72: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/72.jpg)
Scalaz and Semigroup import scalaz.syntax.semigroup._
import scalaz.std.list._
List(1, 2) |+| List(3, 4)
res0: scala.collection.immutable.List[Int] = List(1, 2, 3, 4)
![Page 73: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/73.jpg)
Scalaz and Semigroup import scalaz.syntax.semigroup._
import scalaz.std.string._
"a" |+| "b" |+| "c"
res0: String = abc
![Page 74: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/74.jpg)
/*** A semigroup in type F must satisfy two laws: * * - '''closure''': `∀ a, b in F, append(a, b)` is also in `F`. * - '''associativity''': `∀ a, b, c` in `F`, the equation * `append(append(a, b), c) = append(a, append(b , c))` holds.*/trait SemigroupLaw { def associative(f1: F, f2: F, f3: F)(implicit F: Equal[F]): Boolean = F.equal(append(f1, append(f2, f3)), append(append(f1, f2), f3))}
![Page 75: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/75.jpg)
import scalaz.scalacheck.ScalazProperties._
semigroup.laws[Int].check
+ semigroup.associative: OK, passed 100 tests.
![Page 76: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/76.jpg)
import scalaz.scalacheck.ScalazProperties._
semigroup.laws[String].checksemigroup.laws[Set[Int]].checksemigroup.laws[List[String]].checksemigroup.laws[Map[Int, Int]].check
+ semigroup.associative: OK, passed 100 tests.+ semigroup.associative: OK, passed 100 tests.+ semigroup.associative: OK, passed 100 tests.+ semigroup.associative: OK, passed 100 tests.
![Page 77: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/77.jpg)
import scalaz.scalacheck.ScalazProperties._
semigroup.laws[Map[String, Set[Int]]].check
![Page 78: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/78.jpg)
import scalaz.scalacheck.ScalazProperties._
semigroup.laws[Map[String, Set[Int]]].check
+ semigroup.associative: OK, passed 100 tests.
![Page 79: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/79.jpg)
Map("a" -> Set(1, 2)) |+| Map("a" -> Set(2, 3))
![Page 80: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/80.jpg)
Map("a" -> Set(1, 2)) |+| Map("a" -> Set(2, 3))
res0: ...immutable.Map[...] = Map(a -> Set(1, 2, 3))
![Page 81: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/81.jpg)
Map("a" -> Set(1, 2)) |+| Map("a" -> Set(2, 3))
“Some data structures form interesting semigroups as long as the types of the elements they contain also form semigroups.”
“adapted” from: Functional Programming in Scala - Part 3 - Chapter 10 Monoids
![Page 82: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/82.jpg)
Map("a" -> Map("aa" -> Map("aaa" -> Map("aaaa" -> List(1, 3), "aaab" -> List(2, 4))))) |+| Map("a" -> Map("aa" -> Map("aaa" -> Map("aaaa" -> List(5, 7), "aaab" -> List(6, 8)))))
Map(a->Map(aa->Map(aaa->Map(aaaa->List(1, 3, 5, 7), aaab->List(2, 4, 6, 8)))))
![Page 83: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/83.jpg)
Map("a" -> 1, "b" -> 4) |+| Map("a" -> 2)
![Page 84: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/84.jpg)
Map("a" -> 1, "b" -> 4) |+| Map("a" -> 2)
res0: ...immutable.Map[...] = Map(a -> 3, b -> 4)
![Page 85: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/85.jpg)
1.some |+| 2.someres0: Option[Int] = Some(3)
1.some |+| none[Int]res1: Option[Int] = Some(1)
![Page 86: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/86.jpg)
implicit def optionMonoid[A: Semigroup]: ... def append(f1: Option[A], f2: => Option[A]) = (f1, f2) match { case (Some(a1), Some(a2)) => Some(Semigroup[A].append(a1, a2)) case (Some(a1), None) => f1 case (None, sa2 @ Some(a2)) => sa2 case (None, None) => None }}
![Page 87: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/87.jpg)
Customised Semigroup
case class MeetupOrganiser(name: String, meetup: String, yowCommunityAward: Int)
val jed = MeetupOrganiser("Jed", "scalasyd", 1)val mark = MeetupOrganiser("Mark", "scalasyd", 0)val leo = MeetupOrganiser("Leonardo", "clj-syd", 0)
![Page 88: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/88.jpg)
Customised Semigroup
case class MeetupOrganiser(name: String, meetup: String, yowCommunityAward: Int)
implicit val meetupOrganiserSemigroup = new Semigroup[MeetupOrganiser] { def append(f1: MeetupOrganiser, f2: => MeetupOrganiser): MeetupOrganiser = if (f1.yowCommunityAward >= f2.yowCommunityAward) f1 else f2}
![Page 89: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/89.jpg)
Customised Semigroup
implicit val meetupOrganiserArbitrary: Arbitrary[MeetupOrganiser] = Arbitrary(for { n <- arbitrary[String] m <- arbitrary[String] r <- arbitrary[Int] } yield MeetupOrganiser(n, m, r))
implicit val meetupOrganiserEqual: Equal[MeetupOrganiser] = Equal.equal(_ == _)
semigroup.laws[MeetupOrganiser].check+ semigroup.associative: OK, passed 100 tests.
![Page 90: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/90.jpg)
Customised Semigroup
mark |+| leores0: MeetupOrganiser = MeetupOrganiser(Mark,scalasyd,0)
mark |+| leo |+| jedres1: MeetupOrganiser = MeetupOrganiser(Jed,scalasyd,1)
NonEmptyList(mark, leo, jed).suml1res2: MeetupOrganiser = MeetupOrganiser(Jed,scalasyd,1)
![Page 91: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/91.jpg)
![Page 92: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/92.jpg)
Computer programming as an art (1974)
![Page 93: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/93.jpg)
Map[String, Set[Int]]
![Page 94: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/94.jpg)
![Page 95: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/95.jpg)
Thanks!
February 2015
@filippovitale
![Page 96: Will it Blend? - ScalaSyd February 2015](https://reader033.vdocument.in/reader033/viewer/2022042820/55d1cf32bb61eb732e8b4622/html5/thumbnails/96.jpg)
Questions?
February 2015
@filippovitale