【发布时间】:2011-09-29 09:49:13
【问题描述】:
我知道柯里化的概念和使用方法,但我想知道它在实践中的价值是什么?
【问题讨论】:
标签: functional-programming currying
我知道柯里化的概念和使用方法,但我想知道它在实践中的价值是什么?
【问题讨论】:
标签: functional-programming currying
正如相关问题所涵盖的 Practical use of curried functions? ,人们重视并使用柯里化的原因有很多,包括:
map (+2) 比 map (\x -> x + 2) 更容易阅读
【讨论】:
我发现的真正好处:
更少的错误 - 与命令式控制流相比,通过函数组合来组合代码往往会产生更正确的代码。例如,如果您使用“map”而不是“for 循环”,则可以消除许多“off by one”索引错误的风险
更好的并发性 - 使用纯、无副作用函数创建的代码自动是线程安全的。将其与不可变的持久数据结构结合起来,您就有了编写健壮并发代码的好方法。 Clojure 对此特别有用 - 请参阅 http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey
更简洁和易于管理的代码 - 在我完全不科学的分析中,函数式代码似乎比命令式 OOP 代码短得多。随着程序变得越来越大,这种好处往往会更加明显。我认为这有几个原因:
可测试性 - 当您主要使用纯函数编写代码时,编写健壮的测试非常容易。
当然有一些缺点可以抵消这一点:
【讨论】:
我会说有点像Once and Only Once
我发现自己在 C/C++ 中编写代码,例如
configure_grid (grid, first_column, last_column, action) {
for (i = first_column; i <= last_column; ++i)
// ...
}
configure_grids (action) {
congifure_grid (alpha, first_alpha, last_alpha, action);
congifure_grid (beta, first_beta, last_beta, action);
}
而不是为每个 alpha 和 beta 编写一次 for 循环。这类似于程序代码中的柯里化。这里的优势很明显。
柯里化是一个重要的理论概念,但在实用方面,这是优势。
其实我记得曾经用C写过一个测试套件,有点像这样:
typedef bool (*predicate) (const type *);
const char * argument;
bool do_foo (const type * t) {
return bar (t, argument);
}
bool do_baz (const type * t) {
return bap (t, argument);
}
predicate foo (const char * arg) {
argument = arg;
return do_foo;
}
predicate baz (const char * arg) {
argument = arg;
return do_baz;
}
assert (for_all (data_set("alpha"), foo ("abc")));
assert (for_all (data_set("beta"), baz ("def")));
这都是纯 C 语言,没有宏技巧等。函数式风格,有点像柯里化。这里的好处是你可以一目了然地看到测试用例是什么。 data_set 类似——它将其参数绑定到另一个获取数据的函数:for_all 执行 thunk,检查谓词并清理。整洁。
【讨论】: