kotlin - 带箭头:如何应用 (X)->IO 类型的转换到序列类型的数据获取 IO>?
问题描述
我正在使用 Arrow.kt 学习函数式编程,打算遍历路径层次结构并散列每个文件(并做一些其他事情)。强迫自己尽可能多地使用功能概念。
假设我data class CustomHash(...)
已经在代码中定义了一个。下面会参考。
首先,我需要通过走路径来构建一系列文件。这是一个不纯/有效的函数,因此应该用IO
monad 将其标记为:
fun getFiles(rootPath: File): IO<Sequence<File>> = IO {
rootPath.walk() // This function is of type (File)->Sequence<File>
}
我需要阅读文件。再次,不纯,所以这被标记为IO
fun getRelevantFileContent(file: File): IO<Array<Byte>> {
// Assume some code here to extract only certain data relevant for my hash
}
然后我有一个计算哈希的函数。如果它需要一个字节数组,那么它是完全纯的。之所以这样做,suspend
是因为执行起来会很慢:
suspend fun computeHash(data: Array<Byte>): CustomHash {
// code to compute the hash
}
我的问题是如何以功能性的方式将所有这些链接在一起。
fun main(rootPath: File) {
val x = getFiles(rootPath) // IO<Sequence<File>>
.map { seq -> // seq is of type Sequence<File>
seq.map { getRelevantFileContent(it) } // This produces Sequence<IO<Hash>>
}
}
}
现在,如果我尝试这个,x
是IO<Sequence<IO<Hash>>>
. 我很清楚为什么会这样。
有什么办法可以Sequence<IO<Any>>
变成IO<Sequence<Any>>
? 我想这本质上可能是术语不精确,采用在它们自己的协程中执行的代码块并在同一个协程上运行所有代码块?
如果 Sequence 不存在,我知道IO<IO<Hash>>
可以在那里IO<Hash>
使用 a flatMap
,但Sequence
当然没有 IO 功能的扁平化。
Arrow 的文档有很多“TODO”部分,并且可以非常快速地跳转到假定大量中级/高级函数式编程知识的文档。它对这个问题并没有真正的帮助。
解决方案
First you need to convert the Sequence
to SequenceK
then you can use the sequence
function to do that.
import arrow.fx.*
import arrow.core.*
import arrow.fx.extensions.io.applicative.applicative
val sequenceOfIOs: Sequence<IO<Any>> = TODO()
val ioOfSequence: IO<Sequence<Any>> = sequenceOfIOs.k()
.sequence(IO.applicative())
.fix()
推荐阅读
- php - php中sql查询的列名
- reactjs - 当 React 功能组件中的道具更改时,CodeMirror 值未更新
- python - 如何按行索引将数据框拆分为子数据框
- unity3d - 如何避免在 PREFAB MODE 中调用 OnValidate 方法?
- angular - 材料数据表上的角度材料分页器问题
- react-redux - Antd表过滤多个dataIndex的一个输入?
- android - 在 Canvas 的左右两侧添加文本
- python - 带有 Lat 和 Lon 的 Pandas 数据框行之间的距离矩阵
- python - 带有日期列的 df 在当前和下一行的日期之间添加一个持续时间列
- java - 测量和监控大HashMap的大小