Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.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 为什么可以';我不能把它从Monad推广到Applicative吗?_Haskell_Monads_Applicative - Fatal编程技术网

Haskell 为什么可以';我不能把它从Monad推广到Applicative吗?

Haskell 为什么可以';我不能把它从Monad推广到Applicative吗?,haskell,monads,applicative,Haskell,Monads,Applicative,我将包中的内容概括为winghfreem,类似于将fmap概括为Data.Traversable.mapM import Control.Monad import Control.Monad.Free import Data.Traversable as T hoistFreeM :: (Traversable g, Monad m) => (forall a. f a -> m (g a)) -> Free f b -> m (Free g

我将包中的内容概括为
winghfreem
,类似于将
fmap
概括为
Data.Traversable.mapM

import Control.Monad
import Control.Monad.Free
import Data.Traversable as T

hoistFreeM :: (Traversable g, Monad m) =>
              (forall a. f a -> m (g a)) -> Free f b -> m (Free g b)
hoistFreeM f = go
  where go (Pure x)  = return $ Pure x
        go (Free xs) = liftM Free $ T.mapM go =<< f xs
import-Control.Monad
进口管制,不含单子
导入数据。可作为T进行遍历
(可遍历的g,单子m)=>
(对于所有a.f a->m(g a))->自由f b->m(自由g b)
提升自由度f=go
where go(Pure x)=返回$Pure x

go(Free xs)=liftM Free$T.mapM go=您无法通过免费的Monad提升应用程序,因为Monad结构需要选择(通过
(>>=)
加入
),而应用程序无法提供该选择。但是,也许毫不奇怪,您可以通过一个免费的应用程序提升一个应用程序

-- also from the `free` package
data Ap f a where
  Pure :: a -> Ap f a
  Ap :: f a -> Ap f (a -> b) -> Ap f b

hoistAp :: (forall a. f a -> g a) -> Ap f b -> Ap g b
hoistAp _ (Pure a) = Pure a
hoistAp f (Ap x y) = Ap (f x) (hoistAp f y)

hoistApA :: Applicative v => (forall a. f a -> v (g a)) -> Ap f b -> v (Ap g b)
hoistApA _ (Pure a) = pure (Pure a)
hoistApA f (Ap x y) = Ap <$> f x <*> hoistApA f y

-- just what you'd expect, really
我们可以在这里通过类比继续
mapM
变成
TRAVENSE
,我们可以到达

hoistFreeA f (Free xs) = ?f $ traverse (hoistFreeA f) xs
我一直在使用
?f
作为一个临时类型的孔,试图找出如何前进。我们可以完成这个定义,如果我们能够

?f :: v (f (Free g b)) -> v (Free g b)
换句话说,我们需要将
f
层转换为
g
层,同时生活在
v
层之下。由于
v
是一个
函子
,因此很容易理解
v
,但我们必须将
fa
转换为
ga
的唯一方法是对所有a的参数函数
。f a->v(g a)

我们可以尝试使用
f
以及
Free
包装器来折叠
g

hoistFreeA f (Free xs) = ?f . fmap (fmap Free . f) $ traverse (hoistFreeA f) xs
但现在我们必须解决这个问题

?f :: v (v (Free g b)) -> v (Free g b)

这只是加入,所以我们被卡住了。从根本上说,这是我们永远会陷入困境的地方。自由单子模型单子,因此为了将其封装,我们需要以某种方式
加入
绑定

你的意思是将
单子m
推广到
应用m
,还是
可遍历g
应用g
?我明白是什么立即阻止了我编写函数。我更感兴趣的是关于为什么会发生这种情况的一些理论。你说“自由单子模型单子,因此为了封装它们,我们需要某种方式
join
bind
”,这基本上符合我自己的直觉猜测,但这并不能帮助我理解为什么,例如,我可以编写
traverseFree::(Applicative f,Traversable g)=>(a->fb)->自由ga->f(Free gb)
,但不是
freea::(可遍历的g,应用的h)=>(对于所有的a.f a->h(ga))->Free f b->h(Free g b)
。您需要对输入的
Free
monad的底层
Functor
施加
可遍历的
约束。如果你注意到的话,这就是
traverseFree
的位置。我能做的最好的理论讨论就是比较不同的
Free
树的形状。因为自由单子和应用程序都是初始的,我们知道我们可以使用它们作为模型来讨论这两个类别之间的映射
Free
Monad通过函子合成构建它们的树,而Free
Ap
应用程序通过产品来构建它们的树。如果您所拥有的只是从源函子到目标函子的自然转换(包装在applicative中),那么您不能通过没有
join
的函子组合来应用“向下”,但您可以遍历
(,)
。我不确定您对
可遍历
约束的评论是什么意思。
Traversable
约束位于两个函数中输出
Free
单子的底层
Functor
。也许这就是你的意思。啊,我现在明白了。函子合成是原因。
?f :: v (v (Free g b)) -> v (Free g b)