Search code examples
haskellfrpnetwire

Switching in Netwire


I've been looking for a while, and I think I'm misunderstanding something fundamental regarding switching. Consider the following code

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

Note I'm being extra verbose here just to get the feeling for some of the types involved. What I'm expecting for output is the number 10 repeated for 10 seconds, and then I expect mainwire to switch over to the event returned from mything (because the event from mything is delayed by 10 seconds.) What I'm seeing instead is the main wire inhibiting for 10 seconds, followed by 20. Why am I not seeing the 10's being outputted initially before the switch? I think I'm misunderstanding how switching is supposed to work, and any clarification would be appreciated. Thank you.


Solution

  • The problem lies within now . mycont. now directly turns any a into an Event a, thus switch directly switches to the mycont wire. This wire inhibits for 10 seconds and then outputs 20. To achieve the effect you want, you could use the at function:

    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