【问题标题】:Is there a way to use monad comprehensions with Kotlin Flow有没有办法在 Kotlin Flow 中使用 monad 理解
【发布时间】:2022-02-01 16:15:59
【问题描述】:

Kotlin 协程和 Arrow 是避免嵌套平面图的好方法,在 Kotlin 中引入了单子推导式。然而 Kotlin 的 Flow 类型仍然依赖于声明式平面映射,所以我们混合了直接和声明式风格:

    override suspend fun findAll(page: Pageable): Either<BusinessException, Flow<PageElement<ClientOut>>> = either {
        val count = clientRepository.count().awaitSingle().bind()
        return clientRepository.findByIdNotNull(page).asFlow()
            .flatMapMerge { client ->
                flow { emit(mapDetailedClientOut(client)) }
            }
    }

val count 已绑定在 either {...} 理解中。但是,似乎没有办法对Flow 做同样的事情,迫使我们嵌套一个flatmapMerge()

有没有办法做到这一点,还是计划在不久的将来以某种方式包含在内?

【问题讨论】:

  • 我不相信我们在谈论 回调地狱 时指的是同一件事。 IMO 回调是函数参数的特定用法,主要是在异步过程完成后或在并发过程发生时重复调用某些发起者。我不确定将任何高阶函数与回调地狱相关联是否公平
  • 可能我表达不正确。我正在寻找一种用非阻塞顺序执行替换平面图调用的方法。 arrow-kt.io/docs/patterns/monad_comprehensions 展示了如何对诸如 Either 之类的类型执行此操作,问题是 Flow 不适合此,因此我们必须混合使用 sequentil 样式 (.bind()) 和声明式样式 (Flow.flatmapMerge)。 Scala 的 ZIO 等库允许它使用等效类型 (ZStream) zio.dev/next/datatypes/stream/zstream

标签: kotlin monads kotlin-coroutines arrow-kt


【解决方案1】:

遗憾的是,目前无法理解 KotlinX Flow 数据类型,因为 Kotlin 中的协程仅支持单次发射/bind

因此,只能为具有0..1 元素(例如EitherNullable)的数据类型构建理解,但不能为0..N(例如FlowList 数据类型)构建理解。

【讨论】:

    猜你喜欢
    • 2020-01-08
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-24
    • 2021-06-22
    相关资源
    最近更新 更多