我一直在使用Haxl
monad(這裏描述:http://www.reddit.com/r/haskell/comments/1le4y5/the_haxl_project_at_facebook_slides_from_my_talk),它有一個有趣的特性,<*>
其應用實例與Control.Monad的ap
不同。這是一個關鍵特性,可以在不阻塞的情況下進行併發計算。例如,如果hf
和ha
長計算,然後MaybeT m的應用實例假定Monad m
let hf :: Haxl (a -> b) = ...
ha :: Haxl a = ...
in do
f <- hf
a <- ha
return (f a)
會做他們順序地,而
hf <*> ha
將並行做它們,然後合併結果。
我希望能夠在MaybeT Haxl
運行計算,但問題是,在變壓器包MaybeT m
應用型實例使用一元綁定:
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
(在這裏,(<*>)
在右手邊是爲Maybe
單子,而對非括號的右邊是m
<*>
。)請注意,上下文不同 - 上述實例僅假設爲Applicative m
,而變換器中的實例假定爲Functor m, Monad m
。
我的主要問題是實際的:我該怎麼做呢?我應該推出我自己的MaybeT
monad變壓器嗎?有沒有辦法避開ghc給我的「重複實例聲明」的抱怨,如果我試着寫上面的話?
我也想知道:目前的設置是否存在變壓器封裝的設計缺陷?如果不是,爲什麼不呢?
每個人都傾向於認爲超類實現完全匹配子類實現。哈克斯爾違反了這條不成文的規則,因此無法與其他人打好關係。變形金剛也假設你正在製造'Monad'變形金剛,因此它的實施。 'Applicative'「變形金剛」有更好的結構。 –
@ J.Abrahamson,這不是一個規則,書面或其他。這也不是唯一的情況,其中'<*>'比'ap'更有效。在我看來'MaybeT'在這裏是錯誤的。 – dfeuer
After [AMP](https://www.haskell。org/haskellwiki/Functor-Applicative-Monad_Proposal)作爲GHC 7.10的一部分廣泛傳播,我們可以重寫'Applicative(MaybeT m)'定義。目前'Applicative'不是'Monad'的超類,所以你可能會破壞大量的包。我還看到很多* Foo是Monad的實例,但不是應用程序*警告。會建議現在寫你自己的'MaybeT',或者可能做一個PR到'變形金剛'?. – phadej