【发布时间】:2016-06-19 14:31:58
【问题描述】:
我正在使用 F# 进行数据处理。首先,我将所有文件放在一个目录中,然后处理每个文件以生成一些数据结构。最后,我会将处理后的数据存储到 SQLite 中。我知道,如果我使用 Seq 存储文件名,然后通过管道转发到 Seq.map,它将为每个文件执行惰性处理。但是有这么多文件在内存中包含所有这些文件是不可能的。然后在命令式编程语言中,我可以读取一个文件,处理它,存储它并释放中间数据并执行下一个文件。当然 F# 可以做命令式编程,但我想知道是否有机会以函数式编程风格来做?
files
|> Seq.map readFile
|> Seq.map processContent
|> Seq.map storeProcessResult
上面的代码显示了我的观点。 files 包含一系列文件名,然后我读取文件的内容,将其处理成某种结构,最后将结果存储到数据库中。我知道由于惰性行为,文件将被一一读取和处理。但最终数据何时公布?
【问题讨论】:
-
您遇到错误了吗?你可以用递归来处理它。或者只是使用高阶函数,并使用
use打开文件。您可以轻松地处理将在数据库中填满 10 GB 的数据。 -
那么为什么
Seq不适合你呢?正如你所说的,它很懒,如果Seq.map操作读取文件,然后由Seq.fold处理内容,那么你一次只能在内存中保留一个文件。 -
@FuleSnabel 你的意思是在Seq中,每一个处理过的数据都会被释放吗?
-
@s952163 这里没有错误。在我看来,seq 中的所有 yield 值都将保留在内存中,直到整个管道转发序列运行完毕。也许我在这一点上误解了。
-
这是一个非常典型的工作流程,应该可以工作。您可能需要在其中构建一种方法,以确保释放 readfile 中的文件句柄,而不是保留对 ProcessContent 中数据的引用,并且很可能将 seq.iter 用于 storeProcessResult。 GC 会处理它。由于我们似乎在同一时区,请随时加入chat.stackoverflow.com/rooms/51909/f
标签: f# functional-programming lazy-evaluation