【发布时间】:2020-02-15 23:39:39
【问题描述】:
我正在尝试找出一种方法来向模块的用户隐藏某些辅助函数和相关内容,并认为使用 IIFE 会起作用,但由于无法泛化类型变量而失败了?
我想我已经用下面的代码把它归结为最基本的场景:
module TestA = {
let y = 0;
let x = (type a, numbers: list(a)): option(a) => None;
};
module TestB = {
let x =
(
() => {
let y = 0;
(type a, numbers: list(a)): option(a) => None;
}
)();
};
在 TestB 中编译器抱怨
41 │ };
42 │
43 │ module TestB = {
44 │ let x =
. │ ...
50 │ )();
51 │ };
52 │
53 │ module Number = {
The type of this module contains type variables that cannot be generalized:
{ let x: list('_a) => option('_a); }
This happens when the type system senses there's a mutation/side-effect,
in combination with a polymorphic value.
Using or annotating that value usually solves it. More info:
https://realworldocaml.org/v1/en/html/imperative-programming-1.html#side-effects-and-weak-polymorphism
这是为什么呢?我该如何解决向模块用户隐藏y 的问题?
P.s.:当重新格式化TestB 中的返回类型注释时,会像这样放在None 后面:(type a, numbers: list(a)) => (None: option(a))。为什么在这里而不是在模块TestA 中?据我了解,这只是“标记”返回的值,所以我在这里看不出有什么区别?
【问题讨论】:
标签: polymorphism ocaml iife reason value-restriction