gpt4 book ai didi

haskell - 了解 `mapA` 以获得直觉

转载 作者:行者123 更新时间:2023-12-02 17:00:00 25 4
gpt4 key购买 nike

我正在做 Brent Yorgey 2013 年 UPenn 的练习 lecture实现mapA

mapA::应用 f => (a -> f b) -> ([a] -> f [b])

我正在尝试获得对此功能的直觉。这个功能有什么用呢?我并不是质疑它的实用性 - 只是想了解它。

此外,我正在寻找从 a -> f b[a] -> f [b] 的提示。

最佳答案

如果我们对 f 一无所知,那么像 a -> f b 这样的函数可以让我们将东西放入 f 盒子中,但是那么我们就完全陷入困境了。您可能熟悉Functor。如果我们知道 f 是一个 Functor 那么我们就能够转换 f 内部的东西,但我们仍然基本上陷入困境 - --f 形成一堵我们无法跨越的不动的墙。

我们为什么关心?好吧,当我们尝试构造函数 [a] -> f [b] 时,我们需要了解如何对 a 集合进行操作。如果我们愿意的话,也许我们可以直接拉出第一个(并且它存在)并通过 a -> f b 提供它,然后将结果包装在一个列表中:

unsatisfying :: Functor f => (a -> f b) -> ([a] -> f [b])
unsatisfying inject (a : _) = fmap (\x -> [x]) (inject a)

但我们不仅在 [a] 上有不完整的模式匹配,而且我们显然违反了该函数的精神——我们更愿意使用所有一个。不幸的是,只知道 f 甚至知道 f 是一个 Functor 只能让我们达到

stillUnsatisfying :: Functor f => (a -> f b) -> ([a] -> [f b])
stillUnsatisfying inject as = map inject as

问题是,仅仅因为我们有一个 f 容器的集合并不意味着我们可以找到任何方法来集体对待它们。我们希望以某种方式将我们的集合[f b]“粘合”在一起。如果我们能做到这一点,那么像 [a] -> f [b] 这样的函数听起来就像“将我们的列表 [a] 分解成碎片,将它们分别传递到f 使用 inject,将所有 (f b) 组合在一起,然后在内部重新组装列表”。

显然,我们需要一种将Functor“聚集”在一起的方法,以及一种对f“内部”的单独部分进行操作的方法。

这就是Applicative 的用武之地。不过,我不会准确地介绍它。相反,让我们看一下等效的类型类

class Functor f => Monoidal f where
basic :: a -> f a
glom :: f a -> f b -> f (a, b)

这是一个有趣的练习,可以证明 MonoidalApplicative 是等价的,但您立即可以看到 glom 提供的正是我们想要的东西寻找。此外,basic/pure 使我们能够根据需要将列表的原始片段注入(inject)到 f 中(例如,如果我们的 [a] 为空,那么我们需要将一个空列表注入(inject)到 f 中,而不使用 a -> f b 因为我们不能——看起来像 basic []::f [b])。

因此,Applicative 不仅使您能够在仿函数内部进行转换,还能够将一堆仿函数组合在一起,并对仿函数内部的所有部分进行操作。

关于haskell - 了解 `mapA` 以获得直觉,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27728255/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com