开发者

Stream.of_list with custom data types

I am trying to define a new type of data, to create a list and then to create a stream out of the list:

type 'a myType =  Name of char ;;
let myList = [Name('a')];;
let myStream = Stre开发者_开发百科am.of_list myList;;

Error: The type of this expression, '_a myType Stream.t, contains type variables that cannot be generalized

Any idea?


In your code, myStream is a stream of type myType parametrized by an unknown type (which is called '_a in your error above). The compiler did not find enough information in your code about what '_a should be.

In some cases, the compiler would then generalize the type by stating that '_a can be anything. For instance, myList is properly identified as 'a myType list. However, given that Stream.t is an abstract type, generalization might cause errors, so it is not performed.

One way to work around this is to specify the type of '_a if you only intend it to be used with a single type, for instance with a type constraint :

let myStream : int myType Stream.t = ...

Another way, if you wish to keep it generic, is to turn it into a function (which is then automatically generalized) :

let myStream () = Stream.of_list myList

The type will be unit -> 'a myType Stream.t as expected.

The underlying reason why such generalization might cause errors is the presence of mutable state. Suppose that I define four files as such:

(* 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

This would cause a runtime error. As such, whenever mutable state is involved, types cannot be generalized.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜