gpt4 book ai didi

haskell - 使用 zip 部分应用 <*>

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

我开始查看一些 Haskell 代码并发现:

foo :: ([a] -> [b]) -> [a] -> [(a, b)]
let foo = (<*>) zip

我不明白这是如何工作的,ap 需要一个 f (a -> b) -> f azip 是输入[a] -> [b] -> ([a, b])。我知道 f a -> f b 会匹配 [a] -> [b],但不会匹配 f (a -> b)

最佳答案

让我们手动计算出类型。首先,相关表达式有哪些类型?

(<*>) :: Applicative f => f (a -> b) -> f a -> f b
zip :: [a] -> [b] -> [(a, b)]

现在,我们需要统一zip的类型与 (<*>) 第一个参数的类型。让我们将不相关的重命名为 ab s:

Applicative f => f (a -> b)
[c] -> [d] -> [(c, d)]

首先,什么是f ?我们正在使用什么应用程序?下半部分的类型是一个函数,所以f必须是((->) [c]) ,或“以 c 列表作为输入的函数”。一旦我们这样做了,我们就可以看到:

f ~ ((->) [c])
a ~ [d]
b ~ [(c, d)]

现在我们已经有了匹配的类型,我们可以查找 (<*>) 的定义对于功能:

instance Applicative ((->) a) where
pure = const
(<*>) f g x = f x (g x)

替换zip对于 f在这里,重写为 lambda,得到:

(<*>) zip = \g x -> zip x (g x)

所以,这需要 [a] -> [b] 中的函数和一个[a] ,并用调用函数的结果压缩输入列表。

这在机械上是有意义的,但为什么呢?还有什么更普遍的理解可以让我们得出这个结论,而不必手工解决所有问题呢?我不确定我自己对此的解释是否有用,因此您可能想研究 ((->) t) 的实例。如果您不明白发生了什么,请自行解决。但如果它有用,这里有一个简单的扩展。

((->) t) 的 Functor、Applicative 和 Monad 实例与 Reader t 相同:“对 t 类型的值具有隐式访问的函数”。 (<*>)是关于调用 Applicative 包装器内部的函数,对于函数来说,它是一个双参数函数。它安排将“隐式”参数传递给 f ,产生另一个函数,并使用通过将隐式参数传递给 g 获得的值来调用该函数。以及。所以,(<*>) f ,对于某些人f ,是“给我另一个函数和值 x ,我会将 x 传递给 f 和另一个函数”。

关于haskell - 使用 zip 部分应用 <*>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42261264/

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