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

kyo.seqs.scala Maven / Gradle / Ivy

package kyo

import kyo._
import kyo.core._
import kyo.options._
import scala.collection.mutable.ListBuffer

object seqs {

  final class Seqs private[seqs] () extends Effect[Seq, Seqs] {

    def run[T, S](v: T > (Seqs with S))(implicit f: Flat[T > (Seqs with S)]): Seq[T] > S =
      handle[T, S, Any](v)

    def repeat(n: Int): Unit > Seqs =
      get(Seq.fill(n)(()))

    def get[T, S](v: Seq[T] > S): T > (Seqs with S) =
      v.map {
        case Seq(head) => head
        case _         => suspend(v)
      }

    def filter[S](v: Boolean > S): Unit > (Seqs with S) =
      v.map {
        case true =>
          ()
        case false =>
          drop
      }

    val drop: Nothing > Seqs =
      suspend(Seq.empty[Nothing])

    def traverse[T, U, S, S2](v: Seq[T] > S)(f: T => U > S2): Seq[U] > (S with S2) =
      v.map { v =>
        collect(v.map(f))
      }

    def traverseUnit[T, U, S, S2](v: Seq[T] > S)(f: T => Unit > S2): Unit > (S with S2) =
      v.map { v =>
        def loop(l: Seq[T]): Unit > (S with S2) =
          l match {
            case Seq() => ()
            case h +: t =>
              f(h).andThen(loop(t))
          }
        loop(v)
      }

    def collect[T, S](v: Seq[T > S]): Seq[T] > S = {
      val b = Seq.newBuilder[T]
      def loop(v: Seq[T > S]): Seq[T] > S =
        v match {
          case Seq() =>
            b.result()
          case h +: t =>
            h.map { t1 =>
              b += t1
              loop(t)
            }
        }
      loop(v)
    }

    def fill[T, S](n: Int)(v: => T > S): Seq[T] > S = {
      def loop(n: Int, acc: Seq[T]): Seq[T] > S =
        n match {
          case 0 => acc.reverse
          case n => v.map(v => loop(n - 1, v +: acc))
        }
      loop(n, Seq())
    }

    private implicit val handler: Handler[Seq, Seqs, Any] =
      new Handler[Seq, Seqs, Any] {
        def pure[T](v: T) = Seq(v)
        def apply[T, U, S](v: Seq[T], f: T => U > (Seqs with S)): U > (Seqs with S) = {
          def loop(l: Seq[T], acc: Seq[Seq[U]]): U > (Seqs with S) =
            l match {
              case Seq() =>
                Seqs.get(acc.reverse.flatten: Seq[U])
              case t +: ts =>
                import Flat.unsafe._
                Seqs.run[U, S](f(t)).map(l => loop(ts, l +: acc))
            }
          loop(v, Seq.empty)
        }
      }
  }
  val Seqs = new Seqs
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy