Created
October 31, 2016 18:23
-
-
Save grzegorzbalcerek/ed3b0deacaf320fd4ba9e0d7ec954700 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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