Аппликативный экземпляр для MaybeT m предполагает Monad m
Я используюHaxl
монада (описано здесь:http://www.reddit.com/r/haskell/comments/1le4y5/the_haxl_project_at_facebook_slides_from_my_talk), которая имеет интересную особенность, которая<*>
для его Applicative экземпляр не совпадает сap
из Control.Monad. Это ключевая функция, которая позволяет выполнять параллельные вычисления без блокировки. Например, если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
В пакете трансформаторов используется монадное связывание:
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 $ (<*>) <instance (Applicative m) => Applicative (MaybeT m) where
pure = MaybeT . pure . Just
MaybeT f <*> MaybeT x = MaybeT $ (<*>) <$> f <*> x
gt; f <*> x
(Вот,(<*>)
на правой стороне дляMaybe
монада, а без скобок<*>
на правой стороне дляm
.) Обратите внимание, что контекст отличается - приведенный выше пример предполагает толькоApplicative m
в то время как экземпляр в трансформаторах предполагаетFunctor m, Monad m
.
Мой главный вопрос практичен: что мне с этим делать? Должен ли я свернуть свой собственныйMaybeT
монадный трансформатор? Есть ли способ обойти жалобу «Duplicate instance messages», которую мне дает ghc, если я попытаюсь написать выше?
Я также хотел бы знать: текущая установка - недостаток проекта в пакете трансформаторов? Если нет, то почему?