Я пытаюсь найти способ скрыть определенные вспомогательные функции и связанные с ними вещи от пользователя модуля, и подумал, что использование 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
от пользователя модуля?
Ps: При переформатировании аннотации возвращаемого типа в TestB
ставится после None
, например, так: (type a, numbers: list(a)) => (None: option(a))
,Почему здесь, а не в модуле TestA
? Насколько я понял, это просто «помечает» возвращаемое значение, поэтому я не вижу здесь разницы?