今天早些时候,我为迭代器编写了一个小测试应用程序,它组合了一个用于编写进度的迭代器和一个用于复制数据的迭代器。我最终得到了这样的值:
在查看枚举器库时,我没有发现
第一个函数复制文件,但不显示进度;第二个函数显示进度,但不复制文件。显然,sequence_ 函数对枚举器的迭代器的影响是运行第一个迭代器直到其终止,然后运行另一个迭代器,这不是我想要的。我希望并行运行迭代器而不是串行运行。我感觉自己漏掉了一些明显的东西,但在阅读枚举器库中的 wc 示例时,我看到了这个奇怪的注释:
我想知道这句话是否意味着在枚举框架内组合或组成迭代器不可能。有没有通常被接受的正确方法来解决这个问题?
编辑:似乎没有内置的方法来完成这个任务。Haskell邮件列表中有关于添加组合器(如enumSequence和manyToOne)的讨论,但目前为止,在enumerator软件包中似乎没有提供此功能的任何东西。
-- NOTE: this snippet is with iteratees-0.8.5.0
-- side effect: display progress on stdout
displayProgress :: Iteratee ByteString IO ()
-- side effect: copy the bytestrings of Iteratee to Handle
fileSink :: Handle -> Iteratee ByteString IO ()
writeAndDisplayProgress :: Handle -> Iteratee ByteString IO ()
writeAndDisplayProgress handle = sequence_ [fileSink handle, displayProgress]
在查看枚举器库时,我没有发现
sequence_
或enumWith
的类似物。我想做的就是将两个迭代器组合起来,使它们像一个迭代器一样工作。我可以放弃结果(它将是()
),也可以保留它,我不在乎。我想要的是来自Control.Arrow的(&&&),只是针对迭代器而不是箭头。
我尝试了这两个选项:
-- NOTE: this snippet is with enumerator-0.4.10
run_ $ enumFile source $$ sequence_ [iterHandle handle, displayProgress]
run_ $ enumFile source $$ sequence_ [displayProgress, iterHandle handle]
第一个函数复制文件,但不显示进度;第二个函数显示进度,但不复制文件。显然,sequence_ 函数对枚举器的迭代器的影响是运行第一个迭代器直到其终止,然后运行另一个迭代器,这不是我想要的。我希望并行运行迭代器而不是串行运行。我感觉自己漏掉了一些明显的东西,但在阅读枚举器库中的 wc 示例时,我看到了这个奇怪的注释:
-- Exactly matching wc's output is too annoying, so this example
-- will just print one line per file, and support counting at most
-- one statistic per run
我想知道这句话是否意味着在枚举框架内组合或组成迭代器不可能。有没有通常被接受的正确方法来解决这个问题?
编辑:似乎没有内置的方法来完成这个任务。Haskell邮件列表中有关于添加组合器(如enumSequence和manyToOne)的讨论,但目前为止,在enumerator软件包中似乎没有提供此功能的任何东西。
Enumerator
和Enumeratee
可以以你想要的方式组合。 (附言:我猜你在谈论 Hackage 上的“enumerator”包。你应该在一开始就说出这样的话,因为现在有大约半打不同的迭代器实现。=) - Daniel Wagner