arrow.data.MapKW.kt Maven / Gradle / Ivy
package arrow.data
import arrow.*
import arrow.core.*
import arrow.typeclasses.Applicative
import arrow.typeclasses.Foldable
@higherkind
data class MapKW(val map: Map) : MapKWKind, Map by map {
fun map(f: (A) -> B): MapKW = this.map.map { it.key to f(it.value) }.toMap().k()
fun map2(fb: MapKW, f: (A, B) -> Z): MapKW =
if (fb.isEmpty()) emptyMap().k()
else this.map.flatMap {
(k, a) ->
fb.getOption(k).map { Tuple2(k, f(a, it)) }.k().asIterable()
}.k()
fun map2Eval(fb: Eval>, f: (A, B) -> Z): Eval> =
if (fb.value().isEmpty()) Eval.now(emptyMap().k())
else fb.map { b -> this.map2(b, f) }
fun ap(ff: MapKW B>): MapKW =
ff.flatMap { this.map(it) }
fun ap2(f: MapKW Z>, fb: MapKW): Map =
f.map.flatMap {
(k, f) ->
this.flatMap { a -> fb.flatMap { b -> mapOf(Tuple2(k, f(a, b))).k() } }
.getOption(k).map { Tuple2(k, it) }.k().asIterable()
}.k()
fun flatMap(f: (A) -> MapKW): MapKW =
this.map.flatMap {
(k, v) ->
f(v).getOption(k).map { Tuple2(k, it) }.k().asIterable()
}.k()
fun foldRight(b: Eval, f: (A, Eval) -> Eval): Eval = this.map.values.iterator().iterateRight(b)(f)
fun foldLeft(b: B, f: (B, A) -> B): B = this.map.values.fold(b, f)
fun foldLeft(b: MapKW, f: (MapKW, Tuple2) -> MapKW): MapKW =
this.map.foldLeft(b) { m, (k, v) -> f(m.k(), Tuple2(k, v)) }.k()
fun traverse(f: (A) -> HK, GA: Applicative): HK> =
(Foldable.iterateRight(this.map.iterator(), Eval.always { GA.pure(emptyMap().k()) }))({ kv, lbuf ->
GA.map2Eval(f(kv.value), lbuf) { (mapOf(kv.key to it.a).k() + it.b).k() }
}).value()
companion object
}
fun Map.k(): MapKW = MapKW(this)
fun Option>.k(): MapKW =
when (this) {
is Some -> mapOf(this.t).k()
is None -> emptyMap().k()
}
fun List>.k(): MapKW = this.map { it.key to it.value }.toMap().k()
fun Map.getOption(k: K): Option = Option.fromNullable(this[k])
fun MapKW.updated(k: K, value: A): MapKW {
val mutableMap = this.toMutableMap()
mutableMap.put(k, value)
return mutableMap.toMap().k()
}
fun Map.foldLeft(b: Map, f: (Map, Map.Entry) -> Map): Map {
var result = b
this.forEach { result = f(result, it) }
return result
}
fun Map.foldRight(b: Map, f: (Map.Entry, Map) -> Map): Map =
this.entries.reversed().k().map.foldLeft(b) { x, y -> f(y, x) }
fun Iterator.iterateRight(lb: Eval): (f: (A, Eval) -> Eval) -> Eval = Foldable.iterateRight(this, lb)
fun mapOf(vararg tuple: Tuple2): Map = if (tuple.isNotEmpty()) tuple.map { it.a to it.b }.toMap() else emptyMap()
© 2015 - 2025 Weber Informatics LLC | Privacy Policy