diff --git a/src/main/scala/fs2/interop/cats/Instances.scala b/src/main/scala/fs2/interop/cats/Instances.scala index ca10418..424989b 100644 --- a/src/main/scala/fs2/interop/cats/Instances.scala +++ b/src/main/scala/fs2/interop/cats/Instances.scala @@ -1,8 +1,11 @@ package fs2.interop.cats import fs2.util._ +import fs2.async.immutable.Signal +import fs2.async.mutable.Queue import _root_.cats.{ Eval, Functor => CatsFunctor, Monad => CatsMonad, MonadError } import _root_.cats.arrow.NaturalTransformation +import _root_.cats.functor.Invariant trait Instances extends Instances0 { implicit def effectToMonadError[F[_]](implicit F: Effect[F]): MonadError[F, Throwable] = new MonadError[F, Throwable] { @@ -17,6 +20,20 @@ trait Instances extends Instances0 { implicit def uf1ToNatrualTransformation[F[_], G[_]](implicit uf1: UF1[F, G]): NaturalTransformation[F, G] = new NaturalTransformation[F, G] { def apply[A](fa: F[A]) = uf1(fa) } + + implicit def catsInvariantQueue[F[_]](implicit F: Functor[F]): Invariant[Queue[F, ?]] = + new Invariant[Queue[F, ?]] { + def imap[A, B](fa: Queue[F, A])(f: A => B)(g: B => A): Queue[F, B] = + new Queue[F, B] { + def available: Signal[F, Int] = fa.available + def dequeue1: F[B] = F.map(fa.dequeue1)(f) + def enqueue1(a: B): F[Unit] = fa.enqueue1(g(a)) + def full: Signal[F, Boolean] = fa.full + def offer1(a: B): F[Boolean] = fa.offer1(g(a)) + def size: Signal[F, Int] = fa.size + def upperBound: Option[Int] = fa.upperBound + } + } } private[cats] trait Instances0 extends Instances1 { @@ -38,9 +55,7 @@ private[cats] trait Instances1 extends Instances2 { } private[cats] trait Instances2 { - implicit def functorToCats[F[_]](implicit F: Functor[F]): CatsFunctor[F] = new CatsFunctor[F] { def map[A, B](fa: F[A])(f: A => B) = F.map(fa)(f) } } -