【问题标题】:How should I output values from a list as they are calculated?我应该如何从列表中输出计算值?
【发布时间】:2013-01-06 11:39:32
【问题描述】:

我有一个输出列表的长时间运行的计算。我想在计算时从该列表中输出值。什么是一个巧妙的方法来做到这一点?

目前我使用mapM_ print 将每个值打印到 STDOUT。这对于将值打印到命令行的简单情况来说效果很好,但感觉有点笨拙且难以使用。

此外,在某些时候,我想将我的命令行输出转换为交互式可视化。我怎样才能将我的列表变成类似 FRP 的事件流?能够将其作为事件源插入现有的 GUI 框架会很棒。

重写函数以使用列表以外的其他内容是一种选择,尽管允许我按原样获取列表的解决方案是理想的。

【问题讨论】:

  • 由于 Haskell 中的列表是惰性的,而 mapM_ 也适用于它们,我认为默认解决方案非常好。只需使用hFlush stdout 来确保输出确实被刷新(如mapM_ (hFlush stdout << print)。

标签: haskell frp


【解决方案1】:

这是迭代者和像库这样的迭代者的工作。

使用Proxy 库。

import Control.Proxy

runProxy $ fromListS [1..10] >-> <processing> >-> printD >-> <more> processing>

&lt;processing&gt; 是您需要进行的加法计算。

类似问题:lazy version of mapMIs Haskell's mapM not lazy?

例如:

> labeledPrint label x = putStrLn $ label ++ show x
> runProxy $ fromListS [1..4] >-> printD >-> mapD (*2) 
                              >-> useD (labeledPrint "Second printer: ")
1
Second printer: 2
2
Second printer: 4
3
Second printer: 6
4
Second printer: 8

如果你颠倒应用程序的顺序并使用&lt;-&lt;而不是&gt;-&gt;,那么它看起来就像普通的函数应用程序。

runProxy $ useD (labeledPrint "Second printer: ") <-< mapD (*2)
                                                  <-< printD
                                                  <-< fromListS [1..4]

【讨论】:

  • 如果您不想更改流向下游的值,也可以使用useD 而不是mapMD
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-29
  • 2023-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多