javascript - 如何在 Hindley-Milner 中表示具有多个参数的函数?
问题描述
我正在阅读一个名为Frisby 教授的最充分的函数式编程指南的函数式编程教程,作者对其进行了介绍Hindley-Milner
和几个示例,其中一个是:
// reduce :: (b -> a -> b) -> b -> [a] -> b
var reduce = curry(function(f, x, xs) {
return xs.reduce(f, x);
});
的第一个参数reduce
是一个函数,它的类型签名是b -> a -> b
,这正是我不明白的部分。上面的代码是用 js 编写的,这意味着f
应该接受两个参数并返回一个,如下所示:
function f(b, a) {
return b + a;
}
因此,类型签名f
应该是(b, a) -> b
而不是b -> a -> b
,对吧?f
不应该是一阶函数(由 暗示b -> a -> b
),至少在 js 中不应该。
所以我的问题是,这是教程的错误吗?(b, a) -> b
如果是这样,在 Hindley-Milner中表示的正确方法是什么?
解决方案
我自己浏览了本教程,我认为通常假设函数是咖喱的,所以f
存在b -> a -> b
可能是违反直觉的,但不一定是错误的 AFAIK。(把我说的每一句话都拿在手里;我不是专家;)
然而,签名中的括号f
本身reduce
为读者(至少对 JavaScript 读者)提供了一个重要的线索,它f
是一个函数:
reduce :: (b -> a -> b) -> b -> [a] -> b
^^^^^^^^^^^^^ ^ ^^^ ^
1 2 3 4
1: f
2: reduction initial value
3: list to reduce
4: reduction result
由于f
can be curried,因此无法保证您会一次性收到所有参数。当然,在这种特殊情况下(一个归约函数),大多数人会期望它f
同时应用于两个参数(一个累积值和一个值)。
函数签名仅仅是“意图声明”(至少在 JavaScript 中):
f
有两个参数。- 第一个参数必须是
b
类型。 - 第二个参数必须是一个
a
类型(可以b
与btw相同)。 - 返回值类型是一个
b
类型。
该函数应该做什么没有定义。
如果b
是一个数字,那么这个定义f
很好 AFAIK:(尽管那将是一个非常无用的归约函数)
const f = b => a => 42
推荐阅读
- parameters - 处理类和实例问题
- javascript - jQuery popover 在 Django 应用程序中不起作用?
- reactjs - 在 http-proxy-middleware 的 setupProxy.js 中反应导入环境生成意外标识符
- php - 如何根据当前登录用户codeigniter获取/检索数据,但外键连接到另一个外键
- c# - 在 Unity 中应用多个旋转
- mysql - 参数化查询 - M 语言 (Excel)
- reactjs - 有没有办法为 ReactJs 中的 material-ui 组件提供全局类?
- azure - 从 Azure 数据工厂中的 API 获取而不复制 URL
- c# - 如何用军事时间进行简单的计算?
- angular - 如何根据 HTTP 响应限制/停止 Angular 应用程序加载