【问题标题】:Unzip an event stream of tuple 2 into two streams将元组 2 的事件流解压缩为两个流
【发布时间】:2015-07-28 07:54:02
【问题描述】:

在 reactive-banana 中,给定 Event t (a, b),你会如何引导它到 (Event t a, Event t b)

Traversable#sequence 似乎可以通过 Monad 的一些实例来解决它,因为 (,) 提供了,但 Event t 只是 Functor

【问题讨论】:

    标签: haskell reactive-banana


    【解决方案1】:

    这应该可行:

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

    注意事项:

    • liftA2 (,) 是通用的,因为它只是使用函数的Applicative 实例。在这种情况下,它的等效替代方案是 (&&&) 来自 Control.Arrow。还有一个不那么花哨的选择,\e -> (fst <$> e, snd <$> e)
    • 即使Event tTraversablesequenceA 也无济于事。对 are parametrised only on the second component of the pairFunctorApplicative 实例。你最终会得到一个(a, Event t b) 结果类型,更不用说a 上的Monoid 约束了。

    【讨论】:

    • 再次感谢@duplode 的回答,我也非常感谢您的深入说明。我会查找Arrow,因为我对此很感兴趣。
    • liftA2 (,) 是红鲱鱼,这只是unzipEvent e = (fst <$> e, snd <$> e) 写的无意义。
    • 感谢@Cactus 提供更简单的解决方案!遵循原始组合的类型是一种很好的体验。
    • @Cactus 确实有点。只是我的第一个冲动是fmap fst &&& fmap snd,但由于Control.Arrow 可以说更像是一条红鲱鱼,我改用另一种无点拼写。
    • @RyoichiroOka 丑陋,但应该可以工作:fmap (\(Left x, Right y) -> (x, y)) . uncurry (unionWith (\(x,_) (y,_) -> (x, y))) . (fmap (dup . Left) *** fmap (dup . Right)),与dup x = (x, x)。我为空间写了无点;您可能更喜欢不那么紧凑的版本。 (***) 来自 Control.Arrow,unionWith 来自反应香蕉。对于Either 的最终提取(原则上不安全,但我们知道它会起作用),您可以在either 包中使用Data.Either.Combinators 中的fromLeftfromRight。如果类型相同,则不需要 Either 技巧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-19
    • 1970-01-01
    • 1970-01-01
    • 2011-11-25
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    相关资源
    最近更新 更多