La instancia de aplicación para MaybeT m asume Monad m
He estado usando elHaxl
mónada (descrita aquí:http://www.reddit.com/r/haskell/comments/1le4y5/the_haxl_project_at_facebook_slides_from_my_talk), que tiene la característica interesante de<*>
para su instancia Aplicativa no es lo mismo queap
de Control.Monad. Esta es una característica clave que le permite hacer cálculos concurrentes sin bloquear. Por ejemplo, sihf
yha
son cálculos largos, entonces
let hf :: Haxl (a -> b) = ...
ha :: Haxl a = ...
in do
f <- hf
a <- ha
return (f a)
los hará secuencialmente, mientras
hf <*> ha
los hará en paralelo y luego combinará los resultados.
Me gustaría poder realizar cálculos enMaybeT Haxl
, pero el problema es que la instancia Aplicativa paraMaybeT m
en el paquete de transformadores utiliza enlace monádico:
instance (Functor m, Monad m) => Applicative (MaybeT m) where
pure = return
(<*>) = ap
Dóndeap = liftM2 id
es desdeControl.Monad
. Esto hace
let hmf :: MaybeT Haxl (a -> b) = ...
hma :: MaybeT Haxl a = ...
in hmf <*> hma
correr secuencialmente Parece que una mejor instancia sería más como
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
(Aquí,(<*>)
en el lado derecho es para elMaybe
mónada, mientras que el no entre paréntesis<*>
en el lado derecho es param
.) Tenga en cuenta que el contexto es diferente: la instancia anterior solo suponeApplicative m
, mientras que la instancia en transformadores suponeFunctor m, Monad m
.
Mi pregunta principal es práctica: ¿qué debo hacer al respecto? Debería rodar el míoMaybeT
transformador de mónada? ¿Hay alguna forma de evitar la queja de "Declaraciones de instancias duplicadas" que ghc me da si intento escribir lo anterior?
También me gustaría saber: ¿la configuración actual es un defecto de diseño en el paquete de transformadores? ¿Si no, porque no?