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

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

There is a newer version: 0.8.2
Show newest version
package arrow.data

import arrow.*
import arrow.core.Either

fun  (() -> A).k(): Function0 = Function0(this)

operator fun  Function0Kind.invoke(): A = this.ev().f()

@higherkind
data class Function0(internal val f: () -> A) : Function0Kind {

    fun  map(f: (A) -> B): Function0 = pure(f(this()))

    fun  flatMap(ff: (A) -> Function0Kind): Function0 = ff(f()).ev()

    fun  coflatMap(f: (Function0Kind) -> B): Function0 = { f(this) }.k()

    fun  ap(ff: Function0Kind<(A) -> B>): Function0 = ff.ev().flatMap { f -> map(f) }.ev()

    fun extract(): A = f()

    companion object {

        fun  pure(a: A): Function0 = { a }.k()

        tailrec fun  loop(a: A, f: (A) -> HK>): B {
            val fa = f(a).ev()()
            return when (fa) {
                is Either.Right -> fa.b
                is Either.Left -> loop(fa.a, f)
            }
        }

        fun  tailRecM(a: A, f: (A) -> HK>): Function0 = { loop(a, f) }.k()

    }
}