2016-02-13 139 views
1

如果我有以下幾點:通過拆自定義列表類型

type StringList = StringList of string list 
let sl = StringList [ "Hello, "; "World" ] 
let length = List.length sl 

那麼下面的編譯器錯誤被拋出:

This expression was expected to have type 'a list but here has type StringList 

我的理解是,StringListoption「包裝」 string list,所以我怎麼「打開」它,這樣我可以打電話給List方法呢?

+0

_Context:剛開始學習F#._ –

回答

3

問題是您的StringList類型正在定義一個新類型,該類型是string list的封裝類型。可以在string list上運行的函數在你的包裝器上不起作用,因爲他們對它沒有任何瞭解。

您可以定義StringList作爲一個類型別名 - 因此而不是定義一個新類型,它只是同一事物的一個方便的名字:

type StringList = string list 
let sl : StringList = [ "Hello, "; "World" ] 
let length = List.length sl 

另一種選擇是在調用之前提取string listList.length

type StringList = StringList of string list 

let stringListlength (StringList(slData)) = 
    List.length slData 

let sl = StringList [ "Hello, "; "World" ] 
stringListlength sl 

在第一種方法,你只是定義一個名字,但是編譯器不會做任何檢查,因此,如果您想使用類型標註的名稱(例如,它是唯一有用的)t o讓他們可讀。

在第二種方法中,您確實定義了一種新類型,因此您確保使用StringList的每個人都將使用您定義或使用的功能。

很難說這裏有什麼好的方法,因爲StringList不是很好的例子 - 它不能通過string list傳達任何附加信息。

+0

感謝您的回答。我正在做包裝來獲得類型安全,所以你的第二個選擇正是我所缺少的。非常感謝你! –