haskell - 使用 Netwire 从值生成列表

标签 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 解决此类问题的正确方法的直觉。

最佳答案

注意:这是针对旧版本的 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/

相关文章:

haskell - 最小完整定义 Ord 是如何选择的?

algorithm - Haskell 中的串行理解

oop - 在 Haskell 中扩展数据结构的继承

haskell - 有相当于步进器的网线吗?

haskell 网络: wires of wires

haskell - Map 函数将非函数作为第一个参数

haskell - 尝试组合单子(monad)函数时出错

haskell - Netwire 5 - 墙壁的弹跳物体

haskell - FRP中的“Behavior now”