有没有一种方法可以在Kotlin Flow中使用Monad comprehensions?

3

Kotlin协程和Arrow库是避免嵌套flatmap的好方法,在Kotlin中引入了单子理解。然而,Kotlin的Flow类型仍然依赖于声明式的flatmapping,因此我们会进入直接和声明式风格混合的情况:

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

是否有方法可以实现这一点,或者计划在不久的将来某种方式包含它?


1
当谈到“回调地狱”时,我不认为我们指的是同一件事。在我看来,回调是函数参数的特定用法,主要用于在异步过程完成后或并发过程发生时重复调用某个发起者。我不确定将任何高阶函数与回调地狱联系起来是否公平。 - Joffrey
也许我没有表达清楚。我正在寻找一种用非阻塞顺序执行替换 flatmap 调用的方法。https://arrow-kt.io/docs/patterns/monad_comprehensions/ 展示了如何对 Either 等类型进行操作,但问题是 Flow 不适用于此,因此我们必须混合顺序风格(.bind())和声明性风格(Flow.flatmapMerge)。像 Scala 的 ZIO 这样的库允许对等类型(ZStream)进行操作 https://zio.dev/next/datatypes/stream/zstream/。 - codependent
1个回答

3

不幸的是,目前无法为KotlinX Flow数据类型构建推导式,因为Kotlin中的协程仅支持单次发射/bind

因此,只有像EitherNullable这样具有0..1元素的数据类型才能构建推导式,而不能像FlowList数据类型一样具有0..N元素。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接