В вашем коде myStream
- это поток типа myType
, параметризованный неизвестным типом (который называется '_a
в вашей ошибке выше).Компилятор не нашел в вашем коде достаточно информации о том, каким должен быть '_a
.
В некоторых случаях компилятор затем обобщает тип, утверждая, что '_a
может быть чем угодно.Например, myList
правильно идентифицирован как 'a myType list
.Однако, учитывая, что Stream.t
является абстрактным типом, обобщение может вызвать ошибки, поэтому оно не выполняется.
Один из способов обойти это - указать тип '_a
, если вы только намереваетесь егоиспользоваться с одним типом, например, с ограничением типа:
let myStream : int myType Stream.t = ...
Другой способ, если вы хотите сохранить его универсальным, - превратить его в функцию (которая затем автоматически обобщается):
let myStream () = Stream.of_list myList
Тип будет unit -> 'a myType Stream.t
, как и ожидалось.
Основной причиной, по которой такое обобщение может привести к ошибкам, является наличие изменяемого состояния.Предположим, что я определяю четыре файла следующим образом:
(* ref.ml *)
let x = ref None
(* ref.mli *)
val x : 'a option ref
(* a.ml : 'a = string *)
Ref.x := Some "Hello"
(* b.ml : 'a = int *)
match !ref x with None -> () | Some i -> print_int i
Это может вызвать ошибку во время выполнения.Таким образом, всякий раз, когда задействовано изменяемое состояние, типы не могут быть обобщены.