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

arrow.data.Function1.kt Maven / Gradle / Ivy

package arrow.data

import arrow.core.Either
import arrow.core.andThen
import arrow.core.compose
import arrow.higherkind

fun  ((I) -> O).k(): Function1 = Function1(this)

operator fun  Function1Kind.invoke(i: I): O = this.ev().f(i)

@higherkind
class Function1(val f: (I) -> O) : Function1Kind {

    fun  map(f: (O) -> B): Function1 = f.compose { a: I -> this.f(a) }.k()

    fun  flatMap(f: (O) -> Function1Kind): Function1 = { p: I -> f(this.f(p))(p) }.k()

    fun  ap(ff: Function1Kind B>): Function1 = ff.ev().flatMap { f -> map(f) }.ev()

    fun local(f: (I) -> I): Function1 = f.andThen { this(it) }.k()

    companion object {

        fun  ask(): Function1 = { a: I -> a }.k()

        fun  pure(a: A): Function1 = { _: I -> a }.k()

        tailrec private fun  step(a: A, t: I, fn: (A) -> Function1Kind>): B {
            val af = fn(a)(t)
            return when (af) {
                is Either.Right -> af.b
                is Either.Left -> step(af.a, t, fn)
            }
        }

        fun  tailRecM(a: A, f: (A) -> Function1Kind>): Function1 = { t: I -> step(a, t, f) }.k()
    }
}