Stream.of_list с пользовательскими типами данных - PullRequest
3 голосов
/ 29 марта 2011

Я пытаюсь определить новый тип данных, создать список и затем создать поток из списка:

type 'a myType =  Name of char ;;
let myList = [Name('a')];;
let myStream = Stream.of_list myList;;

Ошибка: тип этого выражения '_a myType Stream.t, содержит переменные типа, которые не могут быть обобщены

Есть идеи?

1 Ответ

5 голосов
/ 29 марта 2011

В вашем коде 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

Это может вызвать ошибку во время выполнения.Таким образом, всякий раз, когда задействовано изменяемое состояние, типы не могут быть обобщены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...