Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save grzegorzbalcerek/ed3b0deacaf320fd4ba9e0d7ec954700 to your computer and use it in GitHub Desktop.
Save grzegorzbalcerek/ed3b0deacaf320fd4ba9e0d7ec954700 to your computer and use it in GitHub Desktop.
trait Monoid[T] {
def id: T
def compose(a: T, b: T): T
}
implicit object ClockMonoid extends Monoid[Int] {
override def id = 12
override def compose(a: Int, b: Int) = (a+b-1)%12+1
}
ClockMonoid.id
ClockMonoid.compose(3, 4)
ClockMonoid.compose(7, 8)
ClockMonoid.compose(9, 12)
def composeAll[T](seq: T*)(implicit m: Monoid[T]): T =
seq.foldLeft(m.id)(m.compose)
composeAll(3, 4)
composeAll(3, 4, 5)
composeAll(3, 4, 5, 6)
implicit object StringMonoid extends Monoid[String] {
override def id = ""
override def compose(a: String, b: String) = a + b
}
composeAll("Hello", " ", "World")
implicit def PairMonoid[S, T](implicit ms: Monoid[S],
mt: Monoid[T]) =
new Monoid[(S, T)] {
override def id = (ms.id, mt.id)
override def compose(a: (S, T), b: (S, T)) =
(ms.compose(a._1, b._1), mt.compose(a._2, b._2))
}
composeAll(("Hello", 3), (" ", 4), ("World", 5))
//
val s2d = (s: String) => s.toDouble
s2d("64.0")
val sqrt = math.sqrt _
sqrt(64.0)
def compose[A,B,C](f: A => B, g: B => C): A => C =
(a) => g(f(a))
val stringSqrt = compose(s2d, sqrt)
stringSqrt("64.0")
def id[A](a: A) = a
val divTen = (x:Double) => x/10.0
divTen(8.0)
val acos = math.acos _
acos(0.8)
def compose4[A,B,C,D,E](
f: A => B,
g: B => C,
h: C => D,
k: D => E): A => E =
compose(compose(f,g),compose(h,k))
def f4 = compose4(s2d, sqrt, divTen, acos)
f4("64.0")
def compose4[A,B,C,D,E](
f: A => B,
g: B => C,
h: C => D,
k: D => E): A => E =
compose(compose(compose(f,g),h),k)
def f4 = compose4(s2d, sqrt, divTen, acos)
f4("64.0")
def compose3[A,B,C,D](f: A => B, g: B => C, h: C => D) =
compose4(f,g,h,id[D])
def f3 = compose3(s2d, sqrt, divTen)
f3("64.0")
def compose3[A,B,C,D](f: A => B, g: B => C, h: C => D) =
compose4(id[A],f,g,h)
def f3 = compose3(s2d, sqrt, divTen)
f3("64.0")
//
//f3("-64.0")
//f3("-20.0.0")
import scala.util.control.Exception._
val s2dO: (String => Option[Double]) = str =>
catching(classOf[NumberFormatException]).opt(str.toDouble)
s2dO("64.0")
s2dO("64.0.")
val sqrtO = (x:Double) =>
if (x >= 0.0) Some(math.sqrt(x)) else None
sqrtO(64.0)
sqrtO(-64.0)
val divTenO = (x:Double) => Option(x/10.0)
divTenO(8.0)
val acosO = (x:Double) =>
if (x >= -1.0 && x <= 1.0)
Some(math.acos(x)) else None
acosO(0.8)
acosO(1.8)
//def f4 = compose4(s2dO, sqrtO, divTenO, acosO)
def compose[A,B,C](f: A => Option[B],
g: B => Option[C]): A => Option[C] =
(a) => f(a) match {
case None => None
case Some(b) => g(b)
}
def id[A](a: A): Option[A] = Some(a)
def compose4[A,B,C,D,E](
f: A => Option[B],
g: B => Option[C],
h: C => Option[D],
k: D => Option[E]): A => Option[E] =
compose(compose(compose(f,g),h),k)
def compose3[A,B,C,D](
f: A => Option[B],
g: B => Option[C],
h: C => Option[D]): A => Option[D] =
compose4(id[A],f,g,h)
def f4 = compose4(s2dO, sqrtO, divTenO, acosO)
def f3 = compose3(s2dO, sqrtO, divTenO)
f4("64.0")
f4("64.0.0")
f4("-64.0")
f4("200.0")
f3("64.0")
f3("64.0.0")
f3("-64.0")
f3("200.0")
val s2dL: (String => List[Double]) = str =>
catching(classOf[NumberFormatException]).
opt(str.toDouble).toList
s2dL("64.0")
s2dL("64.0.")
val sqrtL = (x:Double) =>
if (x >= 0.0) List(math.sqrt(x), -math.sqrt(x)) else Nil
sqrtL(64.0)
sqrtL(-64.0)
val divTenL = (x:Double) => List(x/10.0)
divTenL(8.0)
val acosL = (x:Double) =>
if (x >= -1.0 && x <= 1.0) List(math.acos(x)) else Nil
acosL(0.8)
acosL(1.8)
def compose[A,B,C](f: A => List[B],
g: B => List[C]): A => List[C] =
a => {
val bs = f(a)
var c = List[C]()
bs.foreach(b => c = c ++ g(b))
c
}
def id[A](a: A): List[A] = List(a)
def compose4[A,B,C,D,E](
f: A => List[B],
g: B => List[C],
h: C => List[D],
k: D => List[E]): A => List[E] =
compose(compose(compose(f,g),h),k)
def compose3[A,B,C,D](
f: A => List[B],
g: B => List[C],
h: C => List[D]): A => List[D] =
compose4(id[A],f,g,h)
def f4 = compose4(s2dL, sqrtL, divTenL, acosL)
def f3 = compose3(s2dL, sqrtL, divTenL)
f4("64.0")
f4("64.0.0")
f4("-64.0")
f4("200.0")
f3("64.0")
f3("64.0.0")
f3("-64.0")
f3("200.0")
//def compose[A,B,C](f: A => Option[B],
// g: B => Option[C]): A => Option[C]
//def compose[A,B,C](f: A => List[B],
// g: B => List[C]): A => List[C]
//
//def id[A](a: A): Option[A]
//def id[A](a: A): List[A]
//
//def compose4[A,B,C,D,E](
// f: A => Option[B],
// g: B => Option[C],
// h: C => Option[D],
// k: D => Option[E]): A => Option[E] =
// compose(compose(compose(f,g),h),k)
//
//def compose4[A,B,C,D,E](
// f: A => List[B],
// g: B => List[C],
// h: C => List[D],
// k: D => List[E]): A => List[E] =
// compose(compose(compose(f,g),h),k)
//trait Monoid[T] {
// def id: T
// def compose(a: T, b: T): T
//}
//def composeAll[T](seq: T*)(implicit m: Monoid[T]): T =
// seq.foldLeft(m.id)(m.compose)
import language.higherKinds
trait Monad[M[_]] {
def id[A](a: A): M[A]
def compose[A,B,C](f: A => M[B], g: B => M[C]): A => M[C]
}
def compose4[M[_],A,B,C,D,E](
f: A => M[B],
g: B => M[C],
h: C => M[D],
k: D => M[E])(implicit m: Monad[M]): A => M[E] =
m.compose(m.compose(m.compose(f,g),h),k)
def compose3[M[_],A,B,C,D](
f: A => M[B],
g: B => M[C],
h: C => M[D])(implicit m: Monad[M]): A => M[D] =
compose4(m.id[A],f,g,h)
implicit object optionMonad extends Monad[Option] {
def id[A](a: A): Option[A] = Some(a)
def compose[A,B,C](f: A => Option[B],
g: B => Option[C]): A => Option[C] =
(a) => f(a) match {
case None => None
case Some(b) => g(b)
}
}
implicit object listMonad extends Monad[List] {
def id[A](a: A) = List(a)
def compose[A,B,C](f: A => List[B],
g: B => List[C]): A => List[C] =
(a) => {
val bs = f(a)
var c = List[C]()
bs.foreach(b => c = c ++ g(b))
c
}
}
def f4O = compose4(s2dO, sqrtO, divTenO, acosO)
def f4L = compose4(s2dL, sqrtL, divTenL, acosL)
def f3O = compose3(s2dO, sqrtO, divTenO)
def f3L = compose3(s2dL, sqrtL, divTenL)
f4O("64.0")
f4L("64.0")
f4O("-64.0")
f4L("-64.0")
f3O("64.0")
f3L("64.0")
//def composeAll[T](seq: T*)(implicit m: Monoid[T]): T =
// seq.foldLeft(m.id)(m.compose)
//val f3O = composeAll(sqrtO, divTenO, acosO)
//val f3L = composeAll(sqrtL, divTenL, acosL)
implicit def monad2monoid[F[_],A](implicit m:Monad[F]) =
new Monoid[A => F[A]] {
def id: A => F[A] = m.id
def compose(f: A => F[A], g: A => F[A]): A => F[A] =
m.compose(f, g)
}
val f3O = composeAll(sqrtO, divTenO, acosO)
f3O(64.0)
f3O(-64.0)
f3O(200.0)
val f3L = composeAll(sqrtL, divTenL, acosL)
f3L(64.0)
f3L(-64.0)
f3L(200.0)
trait Monad[M[_]] {
def id[A](a: A): M[A]
def compose[A,B,C](f: A => M[B], g: B => M[C]): A => M[C]
def flatMap[A,B](ma: M[A], f: A => M[B]): M[B] =
compose((_:Unit) => ma, f)(())
def join[A](mma: M[M[A]]): M[A] =
flatMap(mma, identity[M[A]])
def ap[A,B](ma: M[A], mab: M[A => B]): M[B] =
flatMap(ma, (a:A) =>
flatMap(mab, (f:A=>B) =>
id(f(a))))
def map[A,B](ma: M[A], f: A => B): M[B] =
ap(ma, id(f))
}
trait Monad[M[_]] {
def id[A](a: A): M[A]
def flatMap[A,B](ma: M[A], f: A => M[B]): M[B]
def compose[A,B,C](f: A => M[B], g: B => M[C]): A => M[C] =
(a:A) => flatMap(f(a),g)
def join[A](mma: M[M[A]]): M[A] =
flatMap(mma, identity[M[A]])
def ap[A,B](ma: M[A], mab: M[A => B]): M[B] =
flatMap(ma, (a:A) =>
flatMap(mab, (f:A=>B) =>
id(f(a))))
def map[A,B](ma: M[A], f: A => B): M[B] =
ap(ma, id(f))
}
trait Monad[M[_]] {
def id[A](a: A): M[A]
def map[A,B](ma: M[A], f: A => B): M[B]
def join[A](mma: M[M[A]]): M[A]
def flatMap[A,B](ma: M[A], f: A => M[B]): M[B] =
join(map(ma,f))
def compose[A,B,C](f: A => M[B], g: B => M[C]): A => M[C] =
(a:A) => flatMap(f(a),g)
def ap[A,B](ma: M[A], mab: M[A => B]): M[B] =
flatMap(ma, (a:A) =>
flatMap(mab, (f:A=>B) =>
id(f(a))))
}
def f3O(a:Double) =
sqrtO(a).flatMap( b =>
divTenO(b).flatMap( c =>
acosO(c)))
f3O(64.0)
def f3O(a:Double) =
sqrtO(a).flatMap( b =>
divTenO(b).flatMap( c =>
acosO(c).map( d => d )))
def f3O(a:Double) =
sqrtO(a) .flatMap ( b =>
divTenO(b) .flatMap ( c =>
acosO(c) .map ( d =>
d )))
def f3O(a:Double) = for {
b <- sqrtO(a)
c <- divTenO(b)
d <- acosO(c)
} yield d
f3O(64.0)
f3O(-64.0)
f3O(200.0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment