Commit 43988716 authored by Haochen Xie's avatar Haochen Xie

ch10/Monoids.scala - fix a few functions

parent 2cb48d27
......@@ -48,12 +48,18 @@ object Monoids {
}
// Exercise 10.3
def endoMonoid[A] = new Monoid[A => A] {
def coendoMonoid[A] = new Monoid[A => A] {
// hmm, no idea which one should be called first..
override def op(a1: (A) => A, a2: (A) => A): (A) => A = a1 andThen a2
override val zero: (A) => A = Predef.identity
}
def contraendoMonoid[A] = new Monoid[A => A] {
// hmm, no idea which one should be called first..
override def op(a1: (A) => A, a2: (A) => A): (A) => A = a1 compose a2
override val zero: (A) => A = Predef.identity
}
// Exercise 10.4
// will do after looking at Chapter 8
......@@ -64,22 +70,13 @@ object Monoids {
def concatenate[A](as: List[A], m: Monoid[A]): A =
foldMap(as, m)(Predef.identity)
def makePointedMonoid[A](op0: (A, A) => A) = new Monoid[Option[A]] {
override def op(o1: Option[A], o2: Option[A]): Option[A] = (o1, o2) match {
case (None, _) => o2
case (_, None) => o1
case (Some(a1), Some(a2)) => Some(op0(a1, a2))
}
override val zero: Option[A] = Option.empty
}
// Exercise 10.6
def foldLeft[A,B](as: List[A])(z: B)(f: (B, A) => B): B = {
foldMap(as, makePointedMonoid[B=>B]((g1, g2) => z => g2(g1(z))))(a => Some(z => f(z, a))).get(z)
foldMap(as, coendoMonoid[B])(a => z => f(z, a))(z)
}
def foldRight[A,B](as: List[A])(z: B)(f: (A, B) => B): B = {
foldMap(as, makePointedMonoid[B=>B]((g1, g2) => z => g1(g2(z))))(a => Some(z => f(a, z))).get(z)
foldMap(as, contraendoMonoid[B])(a => z => f(a, z))(z)
}
// Exercise 10.7
......@@ -171,19 +168,19 @@ object Monoids {
}
// Exercise 10.12
def foldableList[A] = new Foldable[List[A]] {
def foldableList[A] = new Foldable[List] {
override def foldRight[A, B](as: List[A])(z: B)(f: (A, B) => B): B = as.foldRight(z)(f)
override def foldLeft[A, B](as: List[A])(z: B)(f: (B, A) => B): B = as.foldLeft(z)(f)
override def foldMap[A, B](as: List[A])(f: (A) => B)(m: Monoid[B]): B = Monoids.foldMap(as, m)(f)
}
def foldableIndexSeq[A]= new Foldable[IndexedSeq[A]] {
def foldableIndexSeq[A]= new Foldable[IndexedSeq] {
override def foldRight[A, B](as: IndexedSeq[A])(z: B)(f: (A, B) => B): B = as.foldRight(z)(f)
override def foldLeft[A, B](as: IndexedSeq[A])(z: B)(f: (B, A) => B): B = as.foldLeft(z)(f)
override def foldMap[A, B](as: IndexedSeq[A])(f: (A) => B)(m: Monoid[B]): B = Monoids.foldMapV(as, m)(f)
}
def foldableStream[A] = new Foldable[Stream[A]] {
def foldableStream[A] = new Foldable[Stream] {
override def foldRight[A, B](as: Stream[A])(z: B)(f: (A, B) => B): B = as.foldRight(z)(f)
override def foldLeft[A, B](as: Stream[A])(z: B)(f: (B, A) => B): B = as.foldLeft(z)(f)
override def foldMap[A, B](as: Stream[A])(f: (A) => B)(m: Monoid[B]): B = as.map(f).foldLeft(m.zero)(m.op)
......@@ -194,7 +191,7 @@ object Monoids {
case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]
// Exercise 10.13
def foldableTree[A] = new Foldable[Tree[A]] {
def foldableTree[A] = new Foldable[Tree] {
override def foldRight[A, B](as: Tree[A])(z: B)(f: (A, B) => B): B = as match {
case Leaf(a) => f(a, z)
case Branch(l, r) => foldRight(l)(foldRight(r)(z)(f))(f)
......@@ -210,7 +207,7 @@ object Monoids {
}
// Exercise 10.14
def foldableOption[A] = new Foldable[Option[A]] {
def foldableOption[A] = new Foldable[Option] {
override def foldRight[A, B](as: Option[A])(z: B)(f: (A, B) => B): B = as.foldRight(z)(f)
override def foldLeft[A, B](as: Option[A])(z: B)(f: (B, A) => B): B = as.foldLeft(z)(f)
override def foldMap[A, B](as: Option[A])(f: (A) => B)(m: Monoid[B]): B = as.map(f).foldLeft(m.zero)(m.op)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment