我认为我从根本上误解了如何使用 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 解决此类问题的正确方法的直觉。
最佳答案
注意:这是针对旧版本的 netwire(在事件像现在一样工作之前),因此需要对代码进行一些翻译才能使其在当前版本中正常工作。
如果我没理解错的话,你想要一根电线来产生字符串,然后在完成后进行抑制?有点难说。
once
顾名思义,只产生一次,然后永远禁止。同样,有点不清楚你的电线在做什么(因为你没有告诉我们),但这不是你通常放入“主”电线中的东西(到目前为止,我只使用过一次一次
然后
)。
如果这是正确的,我可能会这样做:
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 获取前一条线的值,并在每个实例中添加前一条线的结果(因此我们必须继续生成 [])。其余的如您所知(我使用类似函数的表示法而不是箭头表示法,因为我更喜欢它,但这对您来说不应该是问题)。
关于haskell - 使用 Netwire 从值生成列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18251054/