2

我认为我从根本上误解了如何使用 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 解决此类问题的正确方法的直觉。

4

1 回答 1

2

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


如果我理解正确的话,你想要一根能产生弦线的电线,然后在它完成时抑制它?这有点难说。

once顾名思义,只产生一次,然后永远抑制。同样,您的电线在做什么有点不清楚(因为您没有告诉我们),但这不是您通常放入“主”电线的东西(到目前为止,我只与 一起使用onceandThen)。

如果这是正确的,我可能会按照以下方式进行操作:

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 [])

括号中的部分产生["adf","nqwer","nzxc"]一瞬间,然后永远产生 []。fifo 从前一条线路中获取值,在每个实例中添加前一条线路的结果(因为我们必须继续产生 [])。其余的如您所知(我使用的是函数式表示法而不是箭头表示法,因为我更喜欢它,但这对您来说应该不是问题)。

于 2013-08-15T17:22:13.343 回答