Search code examples
haskellreactive-banana

Unzip an event stream of tuple 2 into two streams


In reactive-banana, given Event t (a, b), how would you lead it to (Event t a, Event t b)?

Traversable#sequence seems to solve it with some instance of Monad for (,) provided, but Event t is only Functor.


Solution

  • This should work:

    import Control.Applicative
    
    unzipEvent :: Event t (a, b) -> (Event t a, Event t b)
    unzipEvent = liftA2 (,) (fmap fst) (fmap snd)
    

    Notes:

    • The liftA2 (,) is general-purpose, as it is merely using the Applicative instance of functions. In this case, an equivalent alternative to it would be (&&&) from Control.Arrow. There is also a less fancy alternative, \e -> (fst <$> e, snd <$> e).
    • Even if Event t was Traversable, sequenceA wouldn't help. The Functor and Applicative instances for pairs are parametrised only on the second component of the pair. You'd end up with a (a, Event t b) result type, not to mention the Monoid constraint on a.