【发布时间】:2016-02-19 10:51:36
【问题描述】:
当我最终偶然发现Hoogle 时,类型签名的重要性立即让我明白了。您只需搜索类型签名,而不是寻找模棱两可和不精确的函数名称:
inc :: Number a => a -> a
map :: (a -> b) -> [a] -> [b]
head :: [a] -> a
Hoogle 使代码重用成为一流的 :) 由于 Javascript 不是一种纯粹的函数式语言,因此很快就会遇到问题。给出的是这个天真的咖喱实现:
function curry(n, f) {
var args = Array.prototype.slice.call(arguments);
if (typeof n === 'undefined')
args[1] = f.length;
if (n === args.length - 2)
return f.apply(undefined, args.slice(2));
return function() {
return curry.apply(undefined, args.concat(Array.prototype.slice.call(arguments)));
};
}
function add(a, b) { return a + b; }
var addC = curry(2, add);
addC(2)(3); // 5
addC(2, 3); // 5
对应的类型签名是什么样子的?
Number -> ((a1, ..., aN) -> b) -> (a1 -> ... -> aN -> b)
| Number -> ((a1, ..., aN) -> b) -> ((a1, ..., aN) -> b) // ???
这是可怕的,不是预期的结果。在纯函数式语言中,函数总是只有一个参数——在 JavaScript 中是任意数字。
是否有任何约定如何使用 Haskell 的类型签名系统来表达 Javascript 中的不纯语言特性(我猜它是基于 Hindley-Milner 的)?是否有(标准化)对 javascript 的适应?
【问题讨论】:
-
一个更大的问题是首先没有输入 Javascript。
-
我喜欢 javascript 的动态(原型)类型,干杯!
-
@IvenMarquardt,您当然知道动态性质直接与这些签名形成对比?
-
我认为没有任何约定。类型签名对纯函数最有意义,因为它们很容易;如果你想表达一些动态的东西,比如可变参数,你必须想出自己的语法。我见过很多,大多数都可以理解,其他的则不然。
-
Number -> ((a1, …, aN) -> b) -> (a1 -> … -> aN -> b)感觉不错。也许(Number, (a1, …, aN) -> b) -> (a1 -> … -> aN -> b)。你甚至可以使用依赖类型来表示Number是数字或参数N。
标签: javascript types functional-programming type-signature