From 07c4b8bf45308875afdf5e929a385df7bc7bc54c Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 10 Aug 2018 13:11:04 +0700 Subject: [PATCH 1/2] hw3 --- src/main/scala/fpspeedrun/Hw3.scala | 60 +++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/main/scala/fpspeedrun/Hw3.scala diff --git a/src/main/scala/fpspeedrun/Hw3.scala b/src/main/scala/fpspeedrun/Hw3.scala new file mode 100644 index 0000000..64fe4e3 --- /dev/null +++ b/src/main/scala/fpspeedrun/Hw3.scala @@ -0,0 +1,60 @@ +package fpspeedrun + +import cats.Eval + +trait Foldable2[F[_]] { + type LazyMonoid[A] = Monoid[Eval[A]] + type LazyEndo[A] = Eval[A] => Eval[A] + + def endoLazyMonoid[A] = new LazyMonoid[LazyEndo[A]] { + override def empty: Eval[LazyEndo[A]] = Eval.now(x => x) + override def combine(x: Eval[LazyEndo[A]], y: Eval[LazyEndo[A]]): Eval[LazyEndo[A]] = { + Eval.later(t => { + (for { + xv <- x + yv <- y + } yield yv andThen xv).flatMap(_(t)) + }) + } + } + + def foldMapLazy[A, B: LazyMonoid](fa: F[A])(f: A => Eval[B]): Eval[B] + + def foldRightLazy[A, B](fa: F[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = { + val fu: A => Eval[Eval[B] => Eval[B]] = a => Eval.later(f.curried(a)) + foldMapLazy[A, Eval[B] => Eval[B]](fa)(fu)(endoLazyMonoid) + .flatMap(_(lb)) + } +} + +object StreamFoldable2 extends Foldable2[Stream] { + override def foldMapLazy[A, B: StreamFoldable2.LazyMonoid](fa: Stream[A])(f: A => Eval[B]): Eval[B] = { + Eval.now(fa).flatMap { s => + val m = implicitly[StreamFoldable2.LazyMonoid[B]] + if (s.isEmpty) + m.empty + else + m.combine(f(s.head), Eval.defer(foldMapLazy(s.tail)(f))) + } + } +} + +object Main extends App { + def sumN(xs: Stream[Int])(n: Int): Int = { + StreamFoldable2.foldRightLazy[Int, Int => Eval[Int]](xs, Eval.now(_ => Eval.now(0))) { case (el, cntToSum) => + Eval.later(cnt => { + if (cnt <= 0) { + Eval.now(0) + } + else { + for { + f <- cntToSum + v <- f(cnt - 1) + } yield el + v + } + }) + }.flatMap(_(n)).value + } + + println(sumN(Stream.from(1))(10000)) //50005000 +} From d1ccf6bddf689f1dcf8d3df91b75d7adfd37be9c Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 10 Aug 2018 13:14:47 +0700 Subject: [PATCH 2/2] hw3 --- src/main/scala/fpspeedrun/Hw3.scala | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/scala/fpspeedrun/Hw3.scala b/src/main/scala/fpspeedrun/Hw3.scala index 64fe4e3..838a0d9 100644 --- a/src/main/scala/fpspeedrun/Hw3.scala +++ b/src/main/scala/fpspeedrun/Hw3.scala @@ -31,10 +31,7 @@ object StreamFoldable2 extends Foldable2[Stream] { override def foldMapLazy[A, B: StreamFoldable2.LazyMonoid](fa: Stream[A])(f: A => Eval[B]): Eval[B] = { Eval.now(fa).flatMap { s => val m = implicitly[StreamFoldable2.LazyMonoid[B]] - if (s.isEmpty) - m.empty - else - m.combine(f(s.head), Eval.defer(foldMapLazy(s.tail)(f))) + if (s.isEmpty) m.empty else m.combine(f(s.head), Eval.defer(foldMapLazy(s.tail)(f))) } } }