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

cats.instances.vector.scala Maven / Gradle / Ivy

The newest version!
package cats
package instances

import cats.data.ZipVector
import cats.syntax.show._

import scala.annotation.tailrec
import scala.collection.+:
import scala.collection.immutable.VectorBuilder
import cats.data.Ior

trait VectorInstances extends cats.kernel.instances.VectorInstances {
  implicit val catsStdInstancesForVector
    : Traverse[Vector] with Monad[Vector] with Alternative[Vector] with CoflatMap[Vector] with Align[Vector] =
    new Traverse[Vector] with Monad[Vector] with Alternative[Vector] with CoflatMap[Vector] with Align[Vector] {

      def empty[A]: Vector[A] = Vector.empty[A]

      def combineK[A](x: Vector[A], y: Vector[A]): Vector[A] = x ++ y

      def pure[A](x: A): Vector[A] = Vector(x)

      override def map[A, B](fa: Vector[A])(f: A => B): Vector[B] =
        fa.map(f)

      def flatMap[A, B](fa: Vector[A])(f: A => Vector[B]): Vector[B] =
        fa.flatMap(f)

      def coflatMap[A, B](fa: Vector[A])(f: Vector[A] => B): Vector[B] = {
        @tailrec def loop(builder: VectorBuilder[B], as: Vector[A]): Vector[B] =
          as match {
            case _ +: rest => loop(builder += f(as), rest)
            case _         => builder.result()
          }
        loop(new VectorBuilder[B], fa)
      }

      def foldLeft[A, B](fa: Vector[A], b: B)(f: (B, A) => B): B =
        fa.foldLeft(b)(f)

      def foldRight[A, B](fa: Vector[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = {
        def loop(i: Int): Eval[B] =
          if (i < fa.length) f(fa(i), Eval.defer(loop(i + 1))) else lb
        Eval.defer(loop(0))
      }

      override def foldMap[A, B](fa: Vector[A])(f: A => B)(implicit B: Monoid[B]): B =
        B.combineAll(fa.iterator.map(f))

      def tailRecM[A, B](a: A)(fn: A => Vector[Either[A, B]]): Vector[B] = {
        val buf = Vector.newBuilder[B]
        var state = List(fn(a).iterator)
        @tailrec
        def loop(): Unit = state match {
          case Nil => ()
          case h :: tail if h.isEmpty =>
            state = tail
            loop()
          case h :: tail =>
            h.next match {
              case Right(b) =>
                buf += b
                loop()
              case Left(a) =>
                state = (fn(a).iterator) :: h :: tail
                loop()
            }
        }
        loop()
        buf.result
      }

      override def size[A](fa: Vector[A]): Long = fa.size.toLong

      override def get[A](fa: Vector[A])(idx: Long): Option[A] =
        if (idx < Int.MaxValue && fa.size > idx && idx >= 0) Some(fa(idx.toInt)) else None

      override def traverse[G[_], A, B](fa: Vector[A])(f: A => G[B])(implicit G: Applicative[G]): G[Vector[B]] =
        foldRight[A, G[Vector[B]]](fa, Always(G.pure(Vector.empty))) { (a, lgvb) =>
          G.map2Eval(f(a), lgvb)(_ +: _)
        }.value

      override def mapWithIndex[A, B](fa: Vector[A])(f: (A, Int) => B): Vector[B] =
        fa.iterator.zipWithIndex.map(ai => f(ai._1, ai._2)).toVector

      override def zipWithIndex[A](fa: Vector[A]): Vector[(A, Int)] =
        fa.zipWithIndex

      override def exists[A](fa: Vector[A])(p: A => Boolean): Boolean =
        fa.exists(p)

      override def isEmpty[A](fa: Vector[A]): Boolean = fa.isEmpty

      override def foldM[G[_], A, B](fa: Vector[A], z: B)(f: (B, A) => G[B])(implicit G: Monad[G]): G[B] = {
        val length = fa.length
        G.tailRecM((z, 0)) {
          case (b, i) =>
            if (i < length) G.map(f(b, fa(i)))(b => Left((b, i + 1)))
            else G.pure(Right(b))
        }
      }

      override def fold[A](fa: Vector[A])(implicit A: Monoid[A]): A = A.combineAll(fa)

      override def toList[A](fa: Vector[A]): List[A] = fa.toList

      override def reduceLeftOption[A](fa: Vector[A])(f: (A, A) => A): Option[A] =
        fa.reduceLeftOption(f)

      override def find[A](fa: Vector[A])(f: A => Boolean): Option[A] = fa.find(f)

      override def algebra[A]: Monoid[Vector[A]] = new kernel.instances.VectorMonoid[A]

      def functor: Functor[Vector] = this

      def align[A, B](fa: Vector[A], fb: Vector[B]): Vector[A Ior B] = {
        val aLarger = fa.size >= fb.size
        if (aLarger) {
          cats.compat.Vector.zipWith(fa, fb)(Ior.both) ++ fa.drop(fb.size).map(Ior.left)
        } else {
          cats.compat.Vector.zipWith(fa, fb)(Ior.both) ++ fb.drop(fa.size).map(Ior.right)
        }
      }

      override def collectFirst[A, B](fa: Vector[A])(pf: PartialFunction[A, B]): Option[B] = fa.collectFirst(pf)

      override def collectFirstSome[A, B](fa: Vector[A])(f: A => Option[B]): Option[B] =
        fa.collectFirst(Function.unlift(f))
    }

  implicit def catsStdShowForVector[A: Show]: Show[Vector[A]] =
    new Show[Vector[A]] {
      def show(fa: Vector[A]): String =
        fa.iterator.map(_.show).mkString("Vector(", ", ", ")")
    }

  implicit def catsStdNonEmptyParallelForVectorZipVector: NonEmptyParallel.Aux[Vector, ZipVector] =
    new NonEmptyParallel[Vector] {
      type F[x] = ZipVector[x]

      def flatMap: FlatMap[Vector] = cats.instances.vector.catsStdInstancesForVector
      def apply: Apply[ZipVector] = ZipVector.catsDataCommutativeApplyForZipVector

      def sequential: ZipVector ~> Vector =
        λ[ZipVector ~> Vector](_.value)

      def parallel: Vector ~> ZipVector =
        λ[Vector ~> ZipVector](v => new ZipVector(v))
    }
}

private[instances] trait VectorInstancesBinCompat0 {
  implicit val catsStdTraverseFilterForVector: TraverseFilter[Vector] = new TraverseFilter[Vector] {
    val traverse: Traverse[Vector] = cats.instances.vector.catsStdInstancesForVector

    override def mapFilter[A, B](fa: Vector[A])(f: (A) => Option[B]): Vector[B] =
      fa.collect(Function.unlift(f))

    override def filter[A](fa: Vector[A])(f: (A) => Boolean): Vector[A] = fa.filter(f)

    override def filterNot[A](fa: Vector[A])(f: A => Boolean): Vector[A] = fa.filterNot(f)

    override def collect[A, B](fa: Vector[A])(f: PartialFunction[A, B]): Vector[B] = fa.collect(f)

    override def flattenOption[A](fa: Vector[Option[A]]): Vector[A] = fa.flatten

    def traverseFilter[G[_], A, B](fa: Vector[A])(f: (A) => G[Option[B]])(implicit G: Applicative[G]): G[Vector[B]] =
      fa.foldRight(Eval.now(G.pure(Vector.empty[B])))(
          (x, xse) => G.map2Eval(f(x), xse)((i, o) => i.fold(o)(_ +: o))
        )
        .value

    override def filterA[G[_], A](fa: Vector[A])(f: (A) => G[Boolean])(implicit G: Applicative[G]): G[Vector[A]] =
      fa.foldRight(Eval.now(G.pure(Vector.empty[A])))(
          (x, xse) => G.map2Eval(f(x), xse)((b, vec) => if (b) x +: vec else vec)
        )
        .value
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy