Skip to content

Instantly share code, notes, and snippets.

@Odomontois
Last active January 10, 2018 19:22
Show Gist options
  • Save Odomontois/a3f5c8608f40ed4d7fb086ecc89165e4 to your computer and use it in GitHub Desktop.
Save Odomontois/a3f5c8608f40ed4d7fb086ecc89165e4 to your computer and use it in GitHub Desktop.
package notes
import cats.data.{OptionT, Writer}
import cats.free.Free
import cats.instances.option._
import cats.instances.stream._
import cats.instances.vector._
import cats.syntax.applicative._
import cats.syntax.coflatMap._
import cats.syntax.either._
import cats.syntax.foldable._
import cats.syntax.functor._
import cats.syntax.option._
import cats.syntax.writer._
import cats.{Foldable, Monad, _}
import scala.collection.immutable.Seq
object CollectFirst extends App {
implicit class FoldableSyntax[F[_], A](val xs: F[A]) extends AnyVal {
def collectFirstM[B, M[_]](f: A => M[Option[B]])(implicit M: Monad[M], F: Foldable[F]): M[Option[B]] =
xs.foldRight(Now(OptionT.none[M, B]))((x, opt) => Eval.later(OptionT(f(x)).orElse(opt.value))).value.value
def collectFirstSM[B, M[_]](f: A => M[Option[B]])(implicit M: Monad[M], F: Foldable[F]): M[Option[B]] =
xs.foldRight(Now(OptionT.none[Free[M, ?], B]))((x, opt) => Eval.later(OptionT(Free.liftF(f(x))).orElse(opt.value))).value.value.runTailRec
}
implicit class SeqSyntax[F[_], A](val xs: Seq[A]) extends AnyVal {
def collectFirstRecM[B, M[_]](f: A => M[Option[B]])(implicit M: Monad[M]): M[Option[B]] =
M.tailRecM(xs) {
case x +: rest => f(x).map(_.coflatten.toRight(rest))
case _ => none.asRight.pure[M]
}
}
def filterLog[A](f: A => Boolean)(x: A): Writer[Vector[String], Option[A]] =
if (f(x)) Vector(s"found $x").tell as x.some
else Vector(s"dropping $x").tell as none[A]
println(Stream.from(2).collectFirstM(filterLog[Int](10001 % _ == 0) _).written)
println(Stream.from(2).collectFirstSM(filterLog[Int](10009 % _ == 0) _).written)
println(Stream.from(2).collectFirstRecM(filterLog[Int](10009 % _ == 0) _).written)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment