【发布时间】:2015-07-28 07:54:02
【问题描述】:
在 reactive-banana 中,给定 Event t (a, b),你会如何引导它到 (Event t a, Event t b)?
Traversable#sequence 似乎可以通过 Monad 的一些实例来解决它,因为 (,) 提供了,但 Event t 只是 Functor。
【问题讨论】:
在 reactive-banana 中,给定 Event t (a, b),你会如何引导它到 (Event t a, Event t b)?
Traversable#sequence 似乎可以通过 Monad 的一些实例来解决它,因为 (,) 提供了,但 Event t 只是 Functor。
【问题讨论】:
这应该可行:
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 t 是Traversable,sequenceA 也无济于事。对 are parametrised only on the second component of the pair 的 Functor 和 Applicative 实例。你最终会得到一个(a, Event t b) 结果类型,更不用说a 上的Monoid 约束了。【讨论】:
Arrow,因为我对此很感兴趣。
liftA2 (,) 是红鲱鱼,这只是unzipEvent e = (fst <$> e, snd <$> e) 写的无意义。
fmap fst &&& fmap snd,但由于Control.Arrow 可以说更像是一条红鲱鱼,我改用另一种无点拼写。
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 中的fromLeft 和fromRight。如果类型相同,则不需要 Either 技巧。