如何解决参数化多态高阶函数的绑定问题?

时间:2017-08-29 21:56:33

标签: javascript haskell types polymorphism parametric-polymorphism

我正在为Javascript构建一个扩展的运行时类型系统,并且在实现参数多态时遇到一些麻烦。

我已经能够输入多态一阶函数:

const append = Fun("append :: [a] -> [a] -> [a]", xs => ys => xs.concat(ys));

append([1,2]) ([3,4]); // [1,2,3,4]
append([1,2]) (["a","b"]); // fails

顺序函数调用之间共享状态,强制类型注释中的所有a被绑定到相同的具体类型。

然而,一旦我尝试输入更高阶的函数,事情变得更加困难:

const apply = Fun("apply :: (a -> b) -> a -> b", f => x => f(x));
const id = Fun("id :: a -> a", x => x);

apply(id) (2); // 2

问题是函数参数的a / b与高阶函数的apply / const apply = Fun("apply :: (a -> b) -> a -> b", f => x => f(x) + ""); const inc = Fun("inc :: Number -> Number", x => x + 1); apply(inc) (2); // "3" 不同,因为每个函数(在场景后面有一个应用陷阱的代理)都有它的在将范围变量绑定到具体类型的范围上。因此,使用显式类型转换的inc的以下不需要的实现不会失败:

id

直观地,我试图在所有涉及的函数之间保持状态,但这很快就会变得混乱。

另一种方法是根据函数参数的类型注释调整高阶函数的类型注释。函数参数通常是单态的,如apply :: (a -> b) -> a -> b apply f x = f x inc :: Int -> Int inc x = x + 1 :t apply inc -- Int -> Int (a becomes Int, b becomes Int) id :: a -> a id x = x :t apply id -- b -> b (a becomes b, b remains b) ,但有时也是多态的,如sudo stop myapp sleep 10 sudo start myapp 。在这里坚持我的例子是这两种情况的例子:

localhost:3001

好像我需要的只是我的类型注释的两个简单的替换规则 - 没有必要的额外状态。我知道我的推理很简单。问题是,为了获得可靠的参数多态性,它是否太天真。我是不是过分简化了?

0 个答案:

没有答案