Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell MaybeT m的应用实例假定为Monad m_Haskell_Monads_Monad Transformers_Applicative_Haxl - Fatal编程技术网

Haskell MaybeT m的应用实例假定为Monad m

Haskell MaybeT m的应用实例假定为Monad m,haskell,monads,monad-transformers,applicative,haxl,Haskell,Monads,Monad Transformers,Applicative,Haxl,我一直在使用Haxlmonad(这里描述:),它有一个有趣的特性,即它的应用实例的与Control.monad中的ap不同。这是一个关键特性,允许它在不阻塞的情况下进行并发计算。例如,如果hf和ha是长计算,那么 let hf :: Haxl (a -> b) = ... ha :: Haxl a = ... in do f <- hf a <- ha return (f a) 其中ap=liftM2 id来自Control.Monad。这使得 let h

我一直在使用
Haxl
monad(这里描述:),它有一个有趣的特性,即它的应用实例的
与Control.monad中的
ap
不同。这是一个关键特性,允许它在不阻塞的情况下进行并发计算。例如,如果
hf
ha
是长计算,那么

let hf :: Haxl (a -> b) = ...
    ha :: Haxl a = ...
in do
  f <- hf
  a <- ha
  return (f a)
其中
ap=liftM2 id
来自
Control.Monad
。这使得

let hmf :: MaybeT Haxl (a -> b) = ...
    hma :: MaybeT Haxl a = ...
in hmf <*> hma
让hmf::MaybeT Haxl(a->b)=。。。
hma::MaybeT Haxl a=。。。
在hmf hma中
按顺序运行。看起来更好的例子应该是

instance (Applicative m) => Applicative (MaybeT m) where
    pure = MaybeT . pure . Just
    MaybeT f <*> MaybeT x = MaybeT $ (<*>) <$> f <*> x
instance(Applicative m)=>Applicative(MaybeT m)其中
纯=可能。纯净的只是
MaybeT f MaybeT x=MaybeT$()f x
(这里,右侧的
()
代表
Maybe
单子,而右侧的非括号
代表
m
)请注意上下文是不同的——上面的实例只假设
Applicative m
,而transformers中的实例假设
Functor m,单子m

我的主要问题是实用的:对此我应该怎么做?我应该使用自己的
MaybeT
monad transformer吗?如果我试着写上面的内容,ghc会向我抱怨“重复实例声明”,有什么办法可以避免吗

我还想知道:当前设置是否是transformers软件包中的一个设计缺陷?如果不是,为什么不呢?

诀窍在于(与单子不同)应用程序函子是可组合的,因此您不需要(应用程序)转换器,例如
MaybeT
。相反,您可以使用
Compose
将两个应用程序函子组合在一起:

import Control.Applicative
import Data.Functor.Compose

type HaxlM = Compose Haxl Maybe

-- if you prefer to have a function for constructing values:
haxlM :: Haxl (Maybe a) -> HaxlM a
haxlM = Compose
合成始终是
Applicative
的适当实例,并且仅使用其组件的
Applicative
实例。例如:

test = getZipList . getCompose
       $ (+) <$> Compose (ZipList [Just 1,  Nothing, Just 3])
             <*> Compose (ZipList [Nothing, Just 20, Just 30])
test=getZipList。getCompose
$(+)Compose(ZipList[Just 1,Nothing,Just 3])
撰写(ZipList[没有,只有20,只有30])

产生
[没有,没有,只有33]

每个人都倾向于假设超类实现与子类实现完全匹配。Haxl违反了这条不成文的规则,因此无法与他人友好相处。Transformers还假设您正在制作
Monad
转换器,因此它的实现是这样的
Applicative
“变压器”有更好的结构。@J.Abrahamson,这不是一条规则,不管是书面的还是其他的。这也不是唯一一个
在某些重要方面优于
ap
的情况。在我看来,
MaybeT
在这里是错误的。在作为GHC 7.10的一部分广泛传播之后,我们可以重写
Applicative(MaybeT m)
定义。目前,
Applicative
不是
Monad
的超类,因此您可能会破坏许多包。此外,我还意外地看到许多Foo是Monad的实例,但仍然没有应用程序警告。建议您现在就编写自己的
MaybeT
,或者对
transformers
?进行公关。因为这往往是一条不成文的规则。人们通常认为您可以将do语法和
()
语法转换为方便和美观的语法。一旦AMP登陆,这将更加强大,但也将很容易用applicative-only替换这个定义。事实上,这是一个书面规则–它就在Ok,cool中。但在这种情况下,我不能同时使用monad操作,对吗?(一般的Haxl计算同时使用applicative和monad来表示不同的数据流。)是否有某种方法可以充分利用这两个方面(例如,使用ap!=的HaxlM monad,而不必从头编写一个?@davidsd我想没有。你也许可以使用
FlexibleInstances
/
FlexibleContexts
Compose-Haxl-Maybe
创建一个monad实例,但是最好还是从头开始创建
HaxlM
monad。只要我们走在这条路上,值得注意的是,
Applicative
产品也是
Applicative
。与
Applicative
求和相同,只要存在允许偏差工作的自然变换:
import Control.Applicative
import Data.Functor.Compose

type HaxlM = Compose Haxl Maybe

-- if you prefer to have a function for constructing values:
haxlM :: Haxl (Maybe a) -> HaxlM a
haxlM = Compose
test = getZipList . getCompose
       $ (+) <$> Compose (ZipList [Just 1,  Nothing, Just 3])
             <*> Compose (ZipList [Nothing, Just 20, Just 30])