All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tofu.streams.Emits.scala Maven / Gradle / Ivy

package tofu.streams

import cats.{Applicative, Foldable, Monad, MonoidK}
import tofu.lift.Lift
import tofu.syntax.monadic._

trait Emits[F[_]] {

  val monoidK: MonoidK[F]
  val applicative: Applicative[F]

  def emits[C[_], A](as: C[A])(implicit C: Foldable[C]): F[A] =
    C.foldLeft(as, monoidK.empty[A])((acc, a) => monoidK.combineK(acc, applicative.pure(a)))
}

object Emits {

  implicit def instance[F[_]: MonoidK: Applicative]: Emits[F] =
    new Emits[F] {
      override val monoidK: MonoidK[F]         = implicitly
      override val applicative: Applicative[F] = implicitly
    }

  def apply[F[_]](implicit ev: Emits[F]): Emits[F] = ev
}

trait Evals[F[_], G[_]] extends Emits[F] with Lift[G, F] {

  implicit val monad: Monad[F]

  val applicative: Applicative[F] = monad

  def eval[A](ga: G[A]): F[A] = lift(ga)

  def evals[C[_]: Foldable, A](gsa: G[C[A]]): F[A] =
    eval(gsa) >>= (emits(_))

  def evalMap[A, B](fa: F[A])(f: A => G[B]): F[B] =
    fa >>= (a => eval(f(a)))

  def evalFilter[A](fa: F[A])(p: A => G[Boolean]): F[A] =
    fa >>= (a => eval(p(a)).ifM(a.pure, monoidK.empty))
}

object Evals {

  implicit def instance[F[_]: Monad: MonoidK, G[_]](implicit lft: Lift[G, F]): Evals[F, G] =
    new Evals[F, G] {
      override val monad: Monad[F]     = implicitly
      override val monoidK: MonoidK[F] = implicitly

      override def lift[A](fa: G[A]): F[A] = lft.lift(fa)
    }

  def apply[F[_], G[_]](implicit ev: Evals[F, G]): Evals[F, G] = ev
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy