gpt4 book ai didi

function - 常量函数的一种实现如何等于使用 lambda 的版本?

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

我目前正在修改 Haskell 中 lambda (\) 表达式的章节。只是想知道是否有人可以帮助解释这是如何做到的:

const :: a → b → a 
const x _ = x (this part)

定义成这样:

const :: a → (b → a) 
const x = λ_ → x (how did it become like this?)

最佳答案

签名 a -> b -> aa -> (b -> a) 解析完全相同,很多就像算术表达式 1 - 2 - 3(1 - 2) - 3 一样:-> 运算符是右结合的,而 - 运算符是左关联的,即如果没有明确指定,解析器会有效地将括号放在正确的位置。换句话说,A -> B -> C定义为 A -> (B -> C)

如果我们显式编写 a -> (b -> a),那么我们这样做是为了将重点放在处理柯里化(Currying)函数这一事实上,即我们可以接受参数一个接一个,而不是一次全部,但是Haskell中的所有多参数函数无论如何都会被柯里化(Currying)。

至于为什么 const x _ = xconst x =\_ -> x 是等价的:首先,要学究起来,它们不是 等效,请参阅此答案的底部。但我们暂时忽略它。

lambda 和(单个)函数子句都只是定义函数的方法。喜欢,

sqPl1 :: Int -> Int
sqPl1 x = x^2 + 1

做同样的事情

sqPl1 = \x -> x^2 + 1

这只是一种不同的语法。有人会说 f x = ... 符号只是在 lambda 中绑定(bind) x 的语法糖,即 f =\x -> ...,因为 Haskell 基于 lambda 演算,而在 lambda 演算中,lambdas 是编写函数的唯一方法。 (不过这有点过于简单了。)


我说它们不完全等效。我在这里指的是两件事:

  1. 您可以拥有其范围比参数绑定(bind)更持久的本地定义。例如,如果我写

    foo x y = ec * y
    where ec = {- expensive computation depending on `x` -}

    然后 ec 将始终在应用 foo 时从头开始计算。但是,如果我把它写成

    foo x = \y -> ec * y
    where ec = {- expensive computation depending on `x` -}

    然后我可以部分应用 foo 到一个参数,并且可以使用许多不同的 y 值来评估生成的单参数函数,而无需需要再次计算 ec。例如 map (foo 3) [0..90] 使用 lambda 定义会更快。 (另一方面,如果存储的值占用大量内存,则最好保留它;这取决于。)

  2. Haskell 有一个 constant applicative forms 的概念。 .这是一个微妙的话题,我不会在这里讨论,但这可能会受到您是否将函数编写为 lambda 或带有子句或扩展参数的影响。

关于function - 常量函数的一种实现如何等于使用 lambda 的版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71920247/

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