gpt4 book ai didi

haskell - curry 有什么好处?

转载 作者:行者123 更新时间:2023-12-04 04:46:41 25 4
gpt4 key购买 nike

我认为我不太了解柯里化(Currying),因为我看不到它可以提供任何巨大的好处。也许有人可以用一个例子来启发我,说明它为什么如此有用。它真的有好处和应用,还是只是一个被过度欣赏的概念?

最佳答案

(柯里化(Currying)和部分应用之间存在细微差别,尽管它们密切相关;由于它们经常混合在一起,我将同时处理这两个术语。)

我第一次意识到好处的地方是当我看到切片操作符时:

incElems = map (+1)
--non-curried equivalent: incElems = (\elems -> map (\i -> (+) 1 i) elems)

IMO,这很容易阅读。现在,如果 (+) 的类型是 (Int,Int) -> Int *,它是非curried版本,它会(反直觉地)导致错误——但是curryied,它按预期工作,并且具有类型 [Int] -> [Int] .

您在评论中提到了 C# lambdas。在 C# 中,您可以编写 incElems像这样,给定一个函数 plus :
var incElems = xs => xs.Select(x => plus(1,x))

如果您习惯于无点样式,您会看到 x这里是多余的。从逻辑上讲,该代码可以简化为
var incElems = xs => xs.Select(curry(plus)(1))

由于缺少 C# lambdas 的自动部分应用程序,这很糟糕。这是决定柯里化(Currying)在哪里真正有用的关键点:主要是当它隐式发生时。对我来说, map (+1)是最容易阅读的,然后是 .Select(x => plus(1,x)) ,以及带有 curry 的版本如果没有很好的理由,可能应该避免。

现在,如果可读,好处总结为更短、更可读、更简洁的代码——除非有一些滥用无点样式的做法(我确实喜欢 (.).(.),但它是……特别的)

此外,如果不使用 curried 函数,lambda 演算将变得不可能,因为它只有一值(但因此是高阶)函数。

* 当然它实际上在 Num ,但目前这样更具可读性。

更新:currying 是如何工作的。

查看 plus的类型在 C# 中:
int plus(int a, int b) {..}

你必须给它一个值的元组——不是用 C# 术语,而是用数学语言;你不能只忽略第二个值。用haskell的话来说,就是
plus :: (Int,Int) -> Int, 

可以像这样使用
incElem = map (\x -> plus (1, x)) -- equal to .Select (x => plus (1, x))

输入的字符太多了。假设您希望将来更频繁地执行此操作。这里有一个小 helper :
curry f = \x -> (\y -> f (x,y))
plus' = curry plus

这使
incElem = map (plus' 1)

让我们将其应用于具体值。
incElem [1] 
= (map (plus' 1)) [1]
= [plus' 1 1]
= [(curry plus) 1 1]
= [(\x -> (\y -> plus (x,y))) 1 1]
= [plus (1,1)]
= [2]

在这里你可以看到 curry在工作。它将标准的 haskell 风格的函数应用程序 ( plus' 1 1) 转换为对“tupled”函数的调用——或者,从更高级别来看,将“tupled”转换为“untupled”版本。

幸运的是,大多数时候,您不必担心这一点,因为有自动部分应用程序。

关于haskell - curry 有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12413495/

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