首页 > 解决方案 > 在 Haskell 中,如何将嵌套上下文中的函数“应用”到上下文中的值?

问题描述

nestedApply :: (Applicative f, Applicative g) => g (f (a -> b)) -> f a -> g (f b)

如类型所示,如何将其(a->b)应用于a上下文中f

感谢帮助。

标签: functionhaskellapplyapplicative

解决方案


这是专注于类型很有帮助的情况之一。我会尽量保持简单并解释原因。

让我们从描述任务开始。我们有gfab :: g(f(a->b))fa :: f a,我们想拥有g(f b)

gfab :: g (f (a -> b))
fa   :: f a
??1  :: g (f b)

因为g是函子,所以要获得类型,g T我们可以从??2type的值开始g U并应用于. 在我们的例子中,我们有,所以我们正在寻找:fmap??3 :: U -> TT = f b

gfab :: g (f (a -> b))
fa   :: f a
??2  :: g U
??3  :: U -> f b
??1 = fmap ??3 ??2  :: g (f b)

现在,看起来我们应该选择??2 = gfab. 毕竟,这是g Something我们唯一的类型值。我们获得U = f (a -> b).

gfab :: g (f (a -> b))
fa   :: f a
??3  :: f (a -> b) -> f b
??1 = fmap ??3 gfab :: g (f b)

让我们??3变成一个 lambda,\ (x :: f (a->b)) -> ??4??4 :: f b. (的类型x可以省略,但我决定添加它来解释发生了什么)

gfab :: g (f (a -> b))
fa   :: f a
??4  :: f b
??1 = fmap (\ (x :: f (a->b)) -> ??4) gfab :: g (f b)

如何制作??4。好吧,我们有类型f (a->b)和的值f a,所以我们可以<*>得到f b。我们最终得到:

gfab :: g (f (a -> b))
fa   :: f a
??1 = fmap (\ (x :: f (a->b)) -> x <*> fa) gfab :: g (f b)

我们可以将其简化为:

nestedApply gfab fa = fmap (<*> fa) gfab

现在,这不是最优雅的方法,但理解这个过程很重要。


推荐阅读