我一直在使用Haxl
monad(在这里描述:http ://www.reddit.com/r/haskell/comments/1le4y5/the_haxl_project_at_facebook_slides_from_my_talk ),它有一个有趣的特性,<*>
它的 Applicative 实例与ap
Control不同。单子。这是一个关键特性,允许它在不阻塞的情况下进行并发计算。例如,如果hf
和ha
是长计算,那么
let hf :: Haxl (a -> b) = ...
ha :: Haxl a = ...
in do
f <- hf
a <- ha
return (f a)
将按顺序进行,而
hf <*> ha
将并行执行它们,然后合并结果。
我希望能够在 中运行计算MaybeT Haxl
,但问题是MaybeT m
变压器包中的 Applicative 实例使用单子绑定:
instance (Functor m, Monad m) => Applicative (MaybeT m) where
pure = return
(<*>) = ap
ap = liftM2 id
来自哪里Control.Monad
。这使得
let hmf :: MaybeT Haxl (a -> b) = ...
hma :: MaybeT Haxl a = ...
in hmf <*> hma
依次运行。似乎更好的实例更像
instance (Applicative m) => Applicative (MaybeT m) where
pure = MaybeT . pure . Just
MaybeT f <*> MaybeT x = MaybeT $ (<*>) <$> f <*> x
(这里,(<*>)
右侧是monad,而右侧Maybe
未加括号的是。)请注意,上下文是不同的——上面的实例只假设,而转换器中的实例假设。<*>
m
Applicative m
Functor m, Monad m
我的主要问题是实际的:我应该怎么做?我应该推出自己的MaybeT
单子变压器吗?如果我尝试编写上述内容,是否有某种方法可以解决 ghc 给我的“重复实例声明”投诉?
我还想知道:当前设置是变压器包中的设计缺陷吗?如果不是,为什么不呢?