使用Netwire从值中生成列表

时间:2013-08-15 10:42:29

标签: haskell netwire

我认为我从根本上误解了如何用Netwire攻击这类问题:

我有以下测试用例:

我想取一个字符串,将其拆分成行,打印每一行,然后退出。

我遗失的部分是:

  • 如何在管道中提前一个值之后禁止,但是如果该值被拆分并且后来产生结果,则在所有这些结果被消耗之前不会禁止。
  • 主循环功能应该是什么样的
  • 如果我应该使用'一次'

这是我到目前为止的代码:

import Control.Wire

main :: IO ()
main = recur mainWire

recur :: Wire () IO () () -> IO ()
recur a = do
  (e,w) <- stepWire a 0 ()
  case e of Left  () -> return ()
            Right () -> recur w

mainWire :: Wire () IO () ()
mainWire = pure "asdf\nqwer\nzxcv"
       >>> once
       >>> arr lines
       >>> fifo
       >>> arr print
       >>> perform

这输出以下内容:

"asdf"

然后退出。如果我删除once,则程序按预期执行,重复输出完整的行列表。

我想要以下输出:

"asdf"
"qwer"
"zxcv"

我确信我在这里只是缺少一些关于用Netwire解决这类问题的正确方法的直觉。

1 个答案:

答案 0 :(得分:2)

注意:这适用于较旧版本的netwire(在事件发生之前就像现在一样),因此需要对代码进行一些翻译才能使其与当前版本一起正常工作。


如果我理解你是对的,你想要一条产生弦线的电线,然后在它完成时禁止它?这有点难以辨别。

once顾名思义,只产生一次,然后永远地抑制。再一次有点不清楚你的电线在做什么(因为你没有告诉我们)但是它不是你通常放入你的“主”电线的东西(到目前为止我只用过once {{1} }})。

如果这是正确的,我可能会按照以下方式做一些事情:

andThen

(你可以把它写成折叠或其他东西,我只是觉得这有点清楚了。)

如果您不知道,

produceLines s = produceLines' $ lines s where produceLines' [] = inhibit mempty produceLines' (l:ls) = pure s . once --> produceLines' ls 非常适合-->。基本上,这会将传递的字符串拆分为线条,并将它们转换为产生第一行一次的线,然后表现得像一条类似的线,除非第一个元素被移除。一旦产生所有价值,它就会无限期地抑制。

这就是你想要的吗?

更新

我看到你现在要做的事。

您尝试编写的电线可以

完成
andThen

括号中的部分会在一瞬间产生perform . arr print . fifo . ((arr lines . pure "asdf\nqwer\nzxcv" . once) --> pure []) ,然后永久产生[]。 fifo从前一个连线获取值,在每个实例中添加前一个连线的结果(因为我们必须继续生成[])。其余的就像你所知道的那样(我使用类似函数的符号而不是箭头符号,因为我更喜欢它,但这不应该是你的问题。)