具有自定义数据类型的Stream.of_list

时间:2011-03-29 11:08:17

标签: ocaml

我正在尝试定义新类型的数据,创建列表,然后从列表中创建流:

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

错误:此表达式的类型'_a myType Stream.t,        包含无法推广的类型变量

有什么想法吗?

1 个答案:

答案 0 :(得分:5)

在您的代码中,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

这会导致运行时错误。因此,只要涉及可变状态,就不能推广类型。