前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在看 Kotlin Monad,我去。。。看到了一段牛逼的代码:

在看 Kotlin Monad,我去。。。看到了一段牛逼的代码:

作者头像
一个会写诗的程序员
发布2018-12-13 16:17:23
9050
发布2018-12-13 16:17:23
举报
代码语言:javascript
复制
package arrow.typeclasses

import arrow.Kind
import arrow.core.Either
import arrow.core.Eval
import arrow.core.Tuple2
import arrow.core.identity
import kotlin.coroutines.startCoroutine

interface Monad<F> : Applicative<F> {

  fun <A, B> Kind<F, A>.flatMap(f: (A) -> Kind<F, B>): Kind<F, B>

  fun <A, B> tailRecM(a: A, f: (A) -> Kind<F, Either<A, B>>): Kind<F, B>

  override fun <A, B> Kind<F, A>.map(f: (A) -> B): Kind<F, B> =
    flatMap { a -> just(f(a)) }

  override fun <A, B> Kind<F, A>.ap(ff: Kind<F, (A) -> B>): Kind<F, B> =
    ff.flatMap { f -> this.map(f) }

  fun <A> Kind<F, Kind<F, A>>.flatten(): Kind<F, A> =
    flatMap(::identity)

  fun <A, B> Kind<F, A>.followedBy(fb: Kind<F, B>): Kind<F, B> =
    flatMap { fb }

  fun <A, B> Kind<F, A>.followedByEval(fb: Eval<Kind<F, B>>): Kind<F, B> =
    flatMap { fb.value() }

  fun <A, B> Kind<F, A>.effectM(f: (A) -> Kind<F, B>): Kind<F, A> =
    flatMap { a -> f(a).map { a } }

  fun <A, B> Kind<F, A>.forEffect(fb: Kind<F, B>): Kind<F, A> =
    flatMap { a -> fb.map { a } }

  fun <A, B> Kind<F, A>.forEffectEval(fb: Eval<Kind<F, B>>): Kind<F, A> =
    flatMap { a -> fb.value().map { a } }

  fun <A, B> Kind<F, A>.mproduct(f: (A) -> Kind<F, B>): Kind<F, Tuple2<A, B>> =
    flatMap { a -> f(a).map { Tuple2(a, it) } }

  fun <B> Kind<F, Boolean>.ifM(ifTrue: () -> Kind<F, B>, ifFalse: () -> Kind<F, B>): Kind<F, B> =
    flatMap { if (it) ifTrue() else ifFalse() }
}

/**
 * Entry point for monad bindings which enables for comprehension. The underlying implementation is based on coroutines.
 * A coroutine is initiated and suspended inside [MonadErrorContinuation] yielding to [Monad.flatMap]. Once all the flatMap binds are completed
 * the underlying monad is returned from the act of executing the coroutine
 */
fun <F, B> Monad<F>.binding(c: suspend MonadContinuation<F, *>.() -> B): Kind<F, B> {
  val continuation = MonadContinuation<F, B>(this)
  val wrapReturn: suspend MonadContinuation<F, *>.() -> Kind<F, B> = { just(c()) }
  wrapReturn.startCoroutine(continuation, continuation)
  return continuation.returnedMonad()
}

往背后看源代码:

代码语言:javascript
复制
package arrow

interface Kind<out F, out A>
typealias Kind2<F, A, B> = Kind<Kind<F, A>, B>
typealias Kind3<F, A, B, C> = Kind<Kind2<F, A, B>, C>
typealias Kind4<F, A, B, C, D> = Kind<Kind3<F, A, B, C>, D>
typealias Kind5<F, A, B, C, D, E> = Kind<Kind4<F, A, B, C, D>, E>
typealias Kind6<F, A, B, C, D, E, G> = Kind<Kind5<F, A, B, C, D, E>, G>
typealias Kind7<F, A, B, C, D, E, G, H> = Kind<Kind6<F, A, B, C, D, E, G>, H>
typealias Kind8<F, A, B, C, D, E, G, H, I> = Kind<Kind7<F, A, B, C, D, E, G, H>, I>
typealias Kind9<F, A, B, C, D, E, G, H, I, J> = Kind<Kind8<F, A, B, C, D, E, G, H, I>, J>
typealias Kind10<F, A, B, C, D, E, G, H, I, J, K> = Kind<Kind9<F, A, B, C, D, E, G, H, I, J>, K>
typealias Kind11<F, A, B, C, D, E, G, H, I, J, K, L> = Kind<Kind10<F, A, B, C, D, E, G, H, I, J, K>, L>
typealias Kind12<F, A, B, C, D, E, G, H, I, J, K, L, M> = Kind<Kind11<F, A, B, C, D, E, G, H, I, J, K, L>, M>
typealias Kind13<F, A, B, C, D, E, G, H, I, J, K, L, M, N> = Kind<Kind12<F, A, B, C, D, E, G, H, I, J, K, L, M>, N>
typealias Kind14<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O> = Kind<Kind13<F, A, B, C, D, E, G, H, I, J, K, L, M, N>, O>
typealias Kind15<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O, P> = Kind<Kind14<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O>, P>
typealias Kind16<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O, P, Q> = Kind<Kind15<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O, P>, Q>
typealias Kind17<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O, P, Q, R> = Kind<Kind16<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O, P, Q>, R>
typealias Kind18<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O, P, Q, R, S> = Kind<Kind17<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O, P, Q, R>, S>
typealias Kind19<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O, P, Q, R, S, T> = Kind<Kind18<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O, P, Q, R, S>, T>
typealias Kind20<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U> = Kind<Kind19<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O, P, Q, R, S, T>, U>
typealias Kind21<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V> = Kind<Kind20<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U>, V>
typealias Kind22<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W> = Kind<Kind21<F, A, B, C, D, E, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V>, W>


package arrow.typeclasses

import arrow.Kind

interface Invariant<F> {
    fun <A, B> Kind<F, A>.imap(f: (A) -> B, g: (B) -> A): Kind<F, B>
}



package arrow.typeclasses

import arrow.Kind
import arrow.core.Tuple2

interface Functor<F> : Invariant<F> {

  fun <A, B> Kind<F, A>.map(f: (A) -> B): Kind<F, B>

  override fun <A, B> Kind<F, A>.imap(f: (A) -> B, g: (B) -> A): Kind<F, B> =
    map(f)

  fun <A, B> lift(f: (A) -> B): (Kind<F, A>) -> Kind<F, B> =
    { fa: Kind<F, A> ->
      fa.map(f)
    }

  fun <A> Kind<F, A>.void(): Kind<F, Unit> = map { _ -> Unit }

  fun <A, B> Kind<F, A>.fproduct(f: (A) -> B): Kind<F, Tuple2<A, B>> = map { a -> Tuple2(a, f(a)) }

  fun <A, B> Kind<F, A>.`as`(b: B): Kind<F, B> = map { _ -> b }

  fun <A, B> Kind<F, A>.tupleLeft(b: B): Kind<F, Tuple2<B, A>> = map { a -> Tuple2(b, a) }

  fun <A, B> Kind<F, A>.tupleRight(b: B): Kind<F, Tuple2<A, B>> = map { a -> Tuple2(a, b) }

  fun <B, A : B> Kind<F, A>.widen(): Kind<F, B> = this
}


@file:Suppress("UNUSED_PARAMETER")

package arrow.typeclasses

import arrow.Kind
import arrow.core.*
import java.math.BigDecimal

interface Applicative<F> : Functor<F> {

  fun <A> just(a: A): Kind<F, A>

  fun <A> A.just(dummy: Unit = Unit): Kind<F, A> = just(this)

  fun <A, B> Kind<F, A>.ap(ff: Kind<F, (A) -> B>): Kind<F, B>

  fun <A, B> Kind<F, A>.product(fb: Kind<F, B>): Kind<F, Tuple2<A, B>> =
    fb.ap(this.map { a: A -> { b: B -> Tuple2(a, b) } })

  override fun <A, B> Kind<F, A>.map(f: (A) -> B): Kind<F, B> = ap(just(f))

  fun <A, B, Z> Kind<F, A>.map2(fb: Kind<F, B>, f: (Tuple2<A, B>) -> Z): Kind<F, Z> = product(fb).map(f)

  fun <A, B, Z> Kind<F, A>.map2Eval(fb: Eval<Kind<F, B>>, f: (Tuple2<A, B>) -> Z): Eval<Kind<F, Z>> = fb.map { fc -> map2(fc, f) }

  fun <A, B, Z> Kind<F, Tuple2<A, B>>.product(
    other: Kind<F, Z>,
    dummyImplicit: Unit = Unit): Kind<F, Tuple3<A, B, Z>> =
    other.product(this).map { Tuple3(it.b.a, it.b.b, it.a) }

  fun <A, B, C, Z> Kind<F, Tuple3<A, B, C>>.product(
    other: Kind<F, Z>,
    dummyImplicit: Unit = Unit,
    dummyImplicit2: Unit = Unit): Kind<F, Tuple4<A, B, C, Z>> =
    other.product(this).map { Tuple4(it.b.a, it.b.b, it.b.c, it.a) }

  fun <A, B, C, D, Z> Kind<F, Tuple4<A, B, C, D>>.product(
    other: Kind<F, Z>,
    dummyImplicit: Unit = Unit,
    dummyImplicit2: Unit = Unit,
    dummyImplicit3: Unit = Unit): Kind<F, Tuple5<A, B, C, D, Z>> =
    other.product(this).map { Tuple5(it.b.a, it.b.b, it.b.c, it.b.d, it.a) }

  fun <A, B, C, D, E, Z> Kind<F, Tuple5<A, B, C, D, E>>.product(
    other: Kind<F, Z>,
    dummyImplicit: Unit = Unit,
    dummyImplicit2: Unit = Unit,
    dummyImplicit3: Unit = Unit,
    dummyImplicit4: Unit = Unit): Kind<F, Tuple6<A, B, C, D, E, Z>> =
    other.product(this).map { Tuple6(it.b.a, it.b.b, it.b.c, it.b.d, it.b.e, it.a) }

  fun <A, B, C, D, E, FF, Z> Kind<F, Tuple6<A, B, C, D, E, FF>>.product(
    other: Kind<F, Z>,
    dummyImplicit: Unit = Unit,
    dummyImplicit2: Unit = Unit,
    dummyImplicit3: Unit = Unit,
    dummyImplicit4: Unit = Unit,
    dummyImplicit5: Unit = Unit): Kind<F, Tuple7<A, B, C, D, E, FF, Z>> =
    other.product(this).map { Tuple7(it.b.a, it.b.b, it.b.c, it.b.d, it.b.e, it.b.f, it.a) }

  fun <A, B, C, D, E, FF, G, Z> Kind<F, Tuple7<A, B, C, D, E, FF, G>>.product(
    other: Kind<F, Z>,
    dummyImplicit: Unit = Unit,
    dummyImplicit2: Unit = Unit,
    dummyImplicit3: Unit = Unit,
    dummyImplicit4: Unit = Unit,
    dummyImplicit5: Unit = Unit,
    dummyImplicit6: Unit = Unit): Kind<F, Tuple8<A, B, C, D, E, FF, G, Z>> =
    other.product(this).map { Tuple8(it.b.a, it.b.b, it.b.c, it.b.d, it.b.e, it.b.f, it.b.g, it.a) }

  fun <A, B, C, D, E, FF, G, H, Z> Kind<F, Tuple8<A, B, C, D, E, FF, G, H>>.product(
    other: Kind<F, Z>,
    dummyImplicit: Unit = Unit,
    dummyImplicit2: Unit = Unit,
    dummyImplicit3: Unit = Unit,
    dummyImplicit4: Unit = Unit,
    dummyImplicit5: Unit = Unit,
    dummyImplicit6: Unit = Unit,
    dummyImplicit7: Unit = Unit): Kind<F, Tuple9<A, B, C, D, E, FF, G, H, Z>> =
    other.product(this).map { Tuple9(it.b.a, it.b.b, it.b.c, it.b.d, it.b.e, it.b.f, it.b.g, it.b.h, it.a) }

  fun <A, B, C, D, E, FF, G, H, I, Z> Kind<F, Tuple9<A, B, C, D, E, FF, G, H, I>>.product(
    other: Kind<F, Z>,
    dummyImplicit: Unit = Unit,
    dummyImplicit2: Unit = Unit,
    dummyImplicit3: Unit = Unit,
    dummyImplicit4: Unit = Unit,
    dummyImplicit5: Unit = Unit,
    dummyImplicit6: Unit = Unit,
    dummyImplicit7: Unit = Unit,
    dummyImplicit9: Unit = Unit): Kind<F, Tuple10<A, B, C, D, E, FF, G, H, I, Z>> =
    other.product(this).map { Tuple10(it.b.a, it.b.b, it.b.c, it.b.d, it.b.e, it.b.f, it.b.g, it.b.h, it.b.i, it.a) }

  fun <A, B> tupled(
    a: Kind<F, A>,
    b: Kind<F, B>): Kind<F, Tuple2<A, B>> =
    a.product(b)

  fun <A, B, C> tupled(
    a: Kind<F, A>,
    b: Kind<F, B>,
    c: Kind<F, C>): Kind<F, Tuple3<A, B, C>> =
    a.product(b).product(c)

  fun <A, B, C, D> tupled(
    a: Kind<F, A>,
    b: Kind<F, B>,
    c: Kind<F, C>,
    d: Kind<F, D>): Kind<F, Tuple4<A, B, C, D>> =
    a.product(b).product(c).product(d)

  fun <A, B, C, D, E> tupled(
    a: Kind<F, A>,
    b: Kind<F, B>,
    c: Kind<F, C>,
    d: Kind<F, D>,
    e: Kind<F, E>): Kind<F, Tuple5<A, B, C, D, E>> =
    a.product(b).product(c).product(d).product(e)

  fun <A, B, C, D, E, FF> tupled(
    a: Kind<F, A>,
    b: Kind<F, B>,
    c: Kind<F, C>,
    d: Kind<F, D>,
    e: Kind<F, E>,
    f: Kind<F, FF>): Kind<F, Tuple6<A, B, C, D, E, FF>> =
    a.product(b).product(c).product(d).product(e).product(f)

  fun <A, B, C, D, E, FF, G> tupled(
    a: Kind<F, A>,
    b: Kind<F, B>,
    c: Kind<F, C>,
    d: Kind<F, D>,
    e: Kind<F, E>,
    f: Kind<F, FF>,
    g: Kind<F, G>): Kind<F, Tuple7<A, B, C, D, E, FF, G>> =
    a.product(b).product(c).product(d).product(e).product(f).product(g)

  fun <A, B, C, D, E, FF, G, H> tupled(
    a: Kind<F, A>,
    b: Kind<F, B>,
    c: Kind<F, C>,
    d: Kind<F, D>,
    e: Kind<F, E>,
    f: Kind<F, FF>,
    g: Kind<F, G>,
    h: Kind<F, H>): Kind<F, Tuple8<A, B, C, D, E, FF, G, H>> =
    a.product(b).product(c).product(d).product(e).product(f).product(g).product(h)

  fun <A, B, C, D, E, FF, G, H, I> tupled(
    a: Kind<F, A>,
    b: Kind<F, B>,
    c: Kind<F, C>,
    d: Kind<F, D>,
    e: Kind<F, E>,
    f: Kind<F, FF>,
    g: Kind<F, G>,
    h: Kind<F, H>,
    i: Kind<F, I>): Kind<F, Tuple9<A, B, C, D, E, FF, G, H, I>> =
    a.product(b).product(c).product(d).product(e).product(f).product(g).product(h).product(i)

  fun <A, B, C, D, E, FF, G, H, I, J> tupled(
    a: Kind<F, A>,
    b: Kind<F, B>,
    c: Kind<F, C>,
    d: Kind<F, D>,
    e: Kind<F, E>,
    f: Kind<F, FF>,
    g: Kind<F, G>,
    h: Kind<F, H>,
    i: Kind<F, I>,
    j: Kind<F, J>): Kind<F, Tuple10<A, B, C, D, E, FF, G, H, I, J>> =
    a.product(b).product(c).product(d).product(e).product(f).product(g)
      .product(h).product(i).product(j)

  fun <A, B, Z> map(
    a: Kind<F, A>,
    b: Kind<F, B>,
    lbd: (Tuple2<A, B>) -> Z): Kind<F, Z> =
    a.product(b).map(lbd)

  fun <A, B, C, Z> map(
    a: Kind<F, A>,
    b: Kind<F, B>,
    c: Kind<F, C>,
    lbd: (Tuple3<A, B, C>) -> Z): Kind<F, Z> =
    a.product(b).product(c).map(lbd)

  fun <A, B, C, D, Z> map(
    a: Kind<F, A>,
    b: Kind<F, B>,
    c: Kind<F, C>,
    d: Kind<F, D>,
    lbd: (Tuple4<A, B, C, D>) -> Z): Kind<F, Z> =
    a.product(b).product(c).product(d).map(lbd)

  fun <A, B, C, D, E, Z> map(
    a: Kind<F, A>,
    b: Kind<F, B>,
    c: Kind<F, C>,
    d: Kind<F, D>,
    e: Kind<F, E>,
    lbd: (Tuple5<A, B, C, D, E>) -> Z): Kind<F, Z> =
    a.product(b).product(c).product(d).product(e).map(lbd)

  fun <A, B, C, D, E, FF, Z> map(
    a: Kind<F, A>,
    b: Kind<F, B>,
    c: Kind<F, C>,
    d: Kind<F, D>,
    e: Kind<F, E>,
    f: Kind<F, FF>,
    lbd: (Tuple6<A, B, C, D, E, FF>) -> Z): Kind<F, Z> =
    a.product(b).product(c).product(d).product(e).product(f).map(lbd)

  operator fun Kind<F, BigDecimal>.plus(other: Kind<F, BigDecimal>): Kind<F, BigDecimal> =
    map(this, other) { (a, b) -> a + b }

  fun <A, B, C, D, E, FF, G, Z> map(
    a: Kind<F, A>,
    b: Kind<F, B>,
    c: Kind<F, C>,
    d: Kind<F, D>,
    e: Kind<F, E>,
    f: Kind<F, FF>,
    g: Kind<F, G>,
    lbd: (Tuple7<A, B, C, D, E, FF, G>) -> Z): Kind<F, Z> =
    a.product(b).product(c).product(d).product(e).product(f).product(g).map(lbd)

  fun <A, B, C, D, E, FF, G, H, Z> map(
    a: Kind<F, A>,
    b: Kind<F, B>,
    c: Kind<F, C>,
    d: Kind<F, D>,
    e: Kind<F, E>,
    f: Kind<F, FF>,
    g: Kind<F, G>,
    h: Kind<F, H>,
    lbd: (Tuple8<A, B, C, D, E, FF, G, H>) -> Z): Kind<F, Z> =
    a.product(b).product(c).product(d).product(e).product(f)
      .product(g).product(h).map(lbd)

  fun <A, B, C, D, E, FF, G, H, I, Z> map(
    a: Kind<F, A>,
    b: Kind<F, B>,
    c: Kind<F, C>,
    d: Kind<F, D>,
    e: Kind<F, E>,
    f: Kind<F, FF>,
    g: Kind<F, G>,
    h: Kind<F, H>,
    i: Kind<F, I>,
    lbd: (Tuple9<A, B, C, D, E, FF, G, H, I>) -> Z): Kind<F, Z> =
    a.product(b).product(c).product(d).product(e).product(f)
      .product(g).product(h).product(i).map(lbd)

  fun <A, B, C, D, E, FF, G, H, I, J, Z> map(
    a: Kind<F, A>,
    b: Kind<F, B>,
    c: Kind<F, C>,
    d: Kind<F, D>,
    e: Kind<F, E>,
    f: Kind<F, FF>,
    g: Kind<F, G>,
    h: Kind<F, H>,
    i: Kind<F, I>,
    j: Kind<F, J>,
    lbd: (Tuple10<A, B, C, D, E, FF, G, H, I, J>) -> Z): Kind<F, Z> =
    a.product(b).product(c).product(d).product(e).product(f)
      .product(g).product(h).product(i).product(j).map(lbd)

}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.11.15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档