我认为我从根本上误解了如何用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解决这类问题的正确方法的直觉。
答案 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从前一个连线获取值,在每个实例中添加前一个连线的结果(因为我们必须继续生成[])。其余的就像你所知道的那样(我使用类似函数的符号而不是箭头符号,因为我更喜欢它,但这不应该是你的问题。)