在 Netwire 中切换

Switching in Netwire

我已经找了一段时间了,我想我误解了一些关于切换的基本知识。考虑以下代码

mywire :: HasTime t s => Wire s () IO a Int
mywire = pure 10

mycont :: HasTime t s => Wire s () IO a (Wire s () IO a Int)
mycont = after 10 . pure (pure 20)

mycont' :: HasTime t s => Wire s () IO a (Event (Wire s () IO a Int))
mycont' = now . mycont

mything :: HasTime t s => Wire s () IO a (Int, Event (Wire s () IO a Int))
mything = (,) <$> mywire <*> mycont'

mainwire :: (Monad m, HasTime t s) => Wire s () m a Int
mainwire = switch mything

main :: IO ()
main = testWire clockSession_ mainwire

请注意,我在这里说得特别冗长,只是为了了解所涉及的某些类型。我期望输出的是数字 10 重复 10 秒,然后我希望 mainwire 切换到从 mything 返回的事件(因为来自 mything 的事件被延迟10 秒。)我看到的是主线抑制 10 秒,然后是 20 秒。为什么我没有看到 10's 在开关之前最初被输出?我想我误解了切换应该如何工作,如有任何澄清,我们将不胜感激。谢谢。

问题出在now . mycontnow 直接将任何 a 变成 Event a,因此 switch 直接切换到 mycont 线。此线抑制 10 秒,然后输出 20。 要达到你想要的效果,你可以使用at函数:

import Prelude hiding ((.))
import Control.Wire

mywire :: (Monad m, HasTime t s) => Wire s () m a Int
mywire = pure 10

mycont :: (Monad m, HasTime t s) => Wire s () m a (Event (Wire s () m a Int))
mycont = at 10 . pure (pure 20)

mything :: (Monad m, HasTime t s) => Wire s () m a (Int, Event (Wire s () m a Int))
mything = (,) <$> mywire <*> mycont

mainwire :: (Monad m, HasTime t s) => Wire s () m a Int
mainwire = switch mything

main :: IO ()
main = testWire clockSession_ mainwire