2011-03-29 137 views
3

我試圖定義一個新的數據類型,創建一個列表,然後就出了列表的創建流:Stream.of_list與自定義數據類型

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

錯誤:此類型的表達式,'_a myType Stream.t, 包含不能一概而論的類型變量

任何想法?

回答

5

在您的代碼中,myStream是一個類型myType通過未知類型(在您的錯誤中稱爲'_a)參數化的流。編譯器在代碼中找不到關於'_a應該是什麼的足夠信息。

在某些情況下,編譯器會然後指出'_a可以是任何東西概括類型。例如,myList被正確識別爲'a myType list。但是,由於​​是抽象類型,泛化可能會導致錯誤,因此不會執行。要解決此

一種方式是指定的'_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 

這會導致運行時錯誤。因此,無論何時涉及可變狀態,類型都不能一概而論。

+0

謝謝!現在它有很多意義。我刪除'一個和我的用戶定義類型有3種不同的可能類型。 – 2011-03-29 11:30:57