作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我有一个JavaScript函数
function f(x) {
return a(b(x), c(x));
}
最佳答案
通常,将函数转换为无点样式时,没有容易遵循的规则。您要么不得不猜测,要么可以将其自动化。在Haskell IRC频道中,我们拥有lambdabot,它非常适合将Haskell函数转换为无点样式。我通常只是咨询一下,然后在我需要了解它如何工作的情况下往回走。
您可以使用几个有用的函数来解决您的特定示例。我将在下面向您展示它的工作原理,但是请注意,它可能需要花很多时间才能理解。如果您真正了解基本的lambda演算,它也会有所帮助,因为JavaScript语法有时会妨碍您的工作。
无论如何,这里是:
基本上,要正确执行此操作,您需要三个功能:fmap(f, g)
,ap(f, g)
和curry(f)
。有了这些代码后,就可以轻松地将f(x)
定义为(并且在Haskell中看起来更整洁)
f = ap(fmap(curry(a), b), c);
function f(x, y) {
// body
}
f(3, 4)
的方式来调用它们。在函数编程中,这就是所谓的“非函数”。您也可以想象定义函数,例如
function f(x) {
return function(y) {
//body
}
}
f(3)(4)
curry
函数只是采用了像第一个这样的非咖喱函数,然后将其变成了像第二个这样的咖喱函数。
curry
可以定义为
function curry(f) {
return function(a) {
return function(b) {
return f(a, b);
}
}
}
pow(3, 4)
获得81
cpow = curry(pow);
cpow(3)(4);
cpow
是
pow
的咖喱版本。它不会同时使用两个参数,而是将它们分开。在您的特定情况下,这使我们可以从
function f(x) {
return a(b(x), c(x));
}
function f(x) {
return curry(a)(b(x))(c(x));
}
fmap(f, g)
,它接受两个函数作为参数并组成它们。我的意思是
fmap(f, g)(x) == f(g(x))
function fmap(f, g) {
return function(x) {
return f(g(x));
}
}
log(exp(x))
。您可以按照传统方式执行此操作:
function logexp(x) {
return log(exp(x));
}
logexp = fmap(log, exp);
function f(x) {
return curry(a)(b(x))(c(x));
}
fmap
的函数体在视觉上相似。让我们用
fmap
重写它,它变成
function f(x) {
return fmap(curry(a), b)(x)(c(x));
}
f = curry(a)
和
g = b
。
c(x)
的最后一位没有改变。)
ap(f, g)
,它带有两个函数和一个参数,并且做奇怪的事情。我什至不会尝试解释它,所以我只向您展示它的作用:
ap(f, g)(x) == f(x)(g(x))
f
实际上只是两个参数的函数,只是我们写一些稍有不同才能执行魔术。
ap
在JavaScript中定义为
function ap(f, g) {
return function(x) {
return f(x)(g(x));
}
}
function powsqrt(x) {
return pow(x, sqrt(x));
}
ap
的新发现并从关于咖喱的第一部分中记住
cpow
,您还可以
powsqrt = ap(cpow, sqrt);
cpow
是
pow
的咖喱版本。您可以自己验证扩展
ap
的定义是否正确。
function f(x) {
return fmap(curry(a), b)(x)(c(x));
}
ap
的定义,我们可以在这里做些什么,将其转换为无点版本!
function f(x) {
return ap(fmap(curry(a), b), c)(x);
}
ap
的调用。用函数体替换对
ap
的调用!然后,我们仅通过替换就可以得到
function f(x) {
return function(y) {
return fmap(curry(a), b)(y)(c(y));
}(x);
}
x
重命名为
y
。这仍然有些怪异,但是我们可以使其更短一些。毕竟,这与
function f(x) {
return fmap(curry(a), b)(x)(c(x));
}
ap
的调用是正确的。如果愿意,您可以进一步展开此步骤,以了解在说完所有内容后,我们实际上就完成了我们刚开始的工作。我将其保留为练习。
function f(x) {
return ap(fmap(curry(a), b), c)(x);
}
f = ap(fmap(curry(a), b), c);
关于functional-programming - 如何将函数转换为无点形式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16930860/
我是一名优秀的程序员,十分优秀!