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

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()
}

往背后看源代码:

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)

}


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容