arrow.data.SequenceKW.kt Maven / Gradle / Ivy
package arrow.data
import arrow.*
import arrow.core.Either
import arrow.core.Eval
import arrow.core.Tuple2
import arrow.typeclasses.Applicative
fun SequenceKWKind.toList(): List = this.ev().sequence.toList()
@higherkind
data class SequenceKW constructor(val sequence: Sequence) : SequenceKWKind, Sequence by sequence {
fun flatMap(f: (A) -> SequenceKWKind): SequenceKW = this.ev().sequence.flatMap { f(it).ev().sequence }.k()
fun ap(ff: SequenceKWKind<(A) -> B>): SequenceKW = ff.ev().flatMap { f -> map(f) }.ev()
fun map(f: (A) -> B): SequenceKW = this.ev().sequence.map(f).k()
fun foldLeft(b: B, f: (B, A) -> B): B = this.ev().fold(b, f)
fun foldRight(lb: Eval, f: (A, Eval) -> Eval): Eval {
fun loop(fa_p: SequenceKW): Eval = when {
fa_p.sequence.none() -> lb
else -> f(fa_p.first(), Eval.defer { loop(fa_p.drop(1).k()) })
}
return Eval.defer { loop(this.ev()) }
}
fun traverse(f: (A) -> HK, GA: Applicative): HK> =
foldRight(Eval.always { GA.pure(emptySequence().k()) }) { a, eval ->
GA.map2Eval(f(a), eval) { (sequenceOf(it.a) + it.b).k() }
}.value()
fun map2(fb: SequenceKWKind, f: (Tuple2) -> Z): SequenceKW =
this.ev().flatMap { a ->
fb.ev().map { b ->
f(Tuple2(a, b))
}
}.ev()
companion object {
fun pure(a: A): SequenceKW = sequenceOf(a).k()
fun empty(): SequenceKW = emptySequence().k()
fun tailRecM(a: A, f: (A) -> HK>): SequenceKW {
tailrec fun go(
buf: MutableList,
f: (A) -> HK>,
v: SequenceKW>) {
if (!(v.toList().isEmpty())) {
val head: Either = v.first()
when (head) {
is Either.Right -> {
buf += head.b
go(buf, f, v.drop(1).k())
}
is Either.Left -> {
if (v.count() == 1)
go(buf, f, (f(head.a).ev()).k())
else
go(buf, f, (f(head.a).ev() + v.drop(1)).k())
}
}
}
}
val buf = mutableListOf()
go(buf, f, f(a).ev())
return SequenceKW(buf.asSequence())
}
}
}
fun SequenceKW.combineK(y: SequenceKWKind): SequenceKW = (this.sequence + y.ev().sequence).k()
fun Sequence.k(): SequenceKW = SequenceKW(this)
© 2015 - 2025 Weber Informatics LLC | Privacy Policy