首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用辛德雷-米尔纳表示多个参数的函数?

如何用辛德雷-米尔纳表示多个参数的函数?
EN

Stack Overflow用户
提问于 2021-04-14 01:03:29
回答 2查看 122关注 0票数 1

我正在阅读一个名为Frisby教授的“函数式编程指南”的函数式编程教程,作者介绍了Hindley-Milner及其几个例子,其中之一是:

代码语言:javascript
复制
//  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应该使用两个参数并返回一个参数,如下所示:

代码语言:javascript
复制
function f(b, a) {
  return b + a;
}

因此,f的类型签名应该是(b, a) -> b而不是b -> a -> b,对吗?f不应该是一阶函数(由b -> a -> b隐含),至少在js中不应该。

所以我的问题是,这是教程的错误吗?如果是这样的话,用印地语-Milner表示(b, a) -> b的正确方法是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-14 12:59:06

因为xs被注释为[a],所以我们可以期望它是一个常规的javascript数组。

因此,.reduce函数中的reduce调用可以假定为Array.prototype.reduce

此数组方法不接受仓促还原函数。所以我会说:是的,类型注释是错误的。

去修复它

  1. 按照您的建议将类型注释更改为// reduce :: ((b, a) -> b) -> b -> [a] -> b,或
  2. 更改实现以处理将匆匆函数传递给Array.prototype.reduce的问题
代码语言:javascript
复制
//  reduce :: (b -> a -> b) -> b -> [a] -> b
var reduce = curry(function(f, x, xs) {
  return xs.reduce((b, a) => f(b)(a), x);
//                 ^^^^^^^^^^^^^^^^^
});
票数 0
EN

Stack Overflow用户

发布于 2021-04-14 08:27:26

我亲自学习了本教程,我认为通常假定函数是仓促的,所以fb -> a -> b可能是违反直觉的,但也不一定是错误的。(把我说的每句话都听得一清二楚,我不是专家;)

然而,f本身在reduce签名中的括号为读者(至少对JavaScript阅读器)提供了一个重要的线索,即f是一个函数:

代码语言:javascript
复制
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可以被匆忙处理,所以不能保证您一次就能收到它的所有参数。当然,在这种特殊情况下(一个约简函数),大多数人都希望f同时应用于两个参数(累加值和值)。

函数签名只是一个“意向声明”(至少在JavaScript中是这样):

  • f采用两个参数。
  • 第一个参数必须是b类型。
  • 第二个参数必须是a类型(可以与b btw相同)。
  • 返回值类型是b类型。

函数应该做什么没有定义。

如果b是一个数字,那么f的这个定义是很好的AFAIK:(尽管这是一个非常无用的还原函数)

代码语言:javascript
复制
const f = b => a => 42
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67084192

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档