我有一个辅助函数库,我想导出它的柯里化(Currying)版本。
其中一小部分看起来像这样:
export function curry2<A,B,C>(f: (x: A, y: B) => C): (x: A) => (y: B) => C {
return (a) => (b) => f(a, b)
}
function _push<A>(item: A, items: Array<A>): Array<A> {
return items.concat(item)
}
export const push = curry2(push)
但这行不通。 Flow 提示表达式 curry2(push)
,说:
- type parameter 'A' of function call. Missing annotation.
- type parameter 'B' of function call. Missing annotation.
因此我尝试通过注释导出的标识符来解决此问题:
export const push<A>: (item: A) => (items: Array<A>) => Array<A>
但这不起作用,因为 const
表达式无法引入泛型类型变量。
所以我想我必须导出一个实际的函数才能对其进行注释:
export function push<A> (item: A): (items: Array<A>) => Array<A> {
return curry2(_push)(item);
}
但此时我基本上要为每个要导出的函数重写一大块 curry 。
是否有更好的方法来帮助 Flow 在 const 表达式中填充导出的泛型类型变量?
最佳答案
请参阅我对同一问题的回答:https://github.com/facebook/flow/issues/2165#issuecomment-236868389
这里的主要限制是 Flow 根本不推断多态类型。特别是,每当它看到对多态函数的调用时,它都会立即使用新的类型参数实例化类型参数,并且结果永远不会像 Hindley-Milner 系统 ( https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system ) 那样“泛化”。
这种限制的原因是,这种多态类型推断对于子类型来说是不可判定的(参见 Pierce,“Bounded quantification is undecidable”,POPL'92),并且子类型对于 JavaScript 来说是一个必要的功能(但对于 JavaScript 来说则不是那么重要)类似机器学习的语言)。
关于javascript - 导出柯里化(Currying)泛型函数时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38663988/