2012-02-20 22 views
3

我有這個列表的組合:list + undefined list 我寫這個函數來從那裏返回元素的位置。函數將從位置轉換爲元素

let name_of_num list undefined_list len_undefined k = 
    if k < len_undefined then List.nth undefined_list k else 
    List.nth list (k - len_undefined) 

val name_of_num : 'a list -> 'a list -> int -> int -> 'a 

但我的問題是,當我適用於我的功能列表有不同的類型從未定義的列表。所以這個函數不能通過編譯器。 undefined是一個字符串列表。

let len_undefined xsds = List.length (undefined xsds) 

let xsds_of_int xsds = 
List.map (List.map (name_of_num xsds undefined (len_undefined xsds))) 

xsds在我的節目類型xsds。如果我換成undefinedxsds這樣的功能:

let xsds_of_int xsds = 
List.map (List.map (name_of_num xsds xsds (len_undefined xsds))) 

它的工作原理。如何在k < len_undefined時寫第二個條件?

let name_of_num list len_undefined k = 
    if k < len_undefined then ??? else 
    List.nth list (k - len_undefined) 

謝謝。

回答

3

你要求的東西似乎是不可能的。你想提供兩種不同類型的列表。但是你的函數有時會返回一個list的元素,有時會返回一個undefined_list的元素。由於OCaml是強類型語言,因此函數必須始終返回相同類型的值。因此,listundefined_list必須具有相同的類型。

如果不理解您的要求,很難知道該建議什麼。但是,定義一個新的類型非常簡單,該類型結合了您喜歡的任何兩種類型。 (或任何有限數量的類型。)

type either = A of typea | B of typeb 

的值(A x)表示的typea的值並將該值(B y)表示的typeb的值。但是這兩個值是相同的類型,類型爲either

然後,您將定義name_of_num以獲取兩個不同類型的列表,但它將返回類型either。如果你想更有趣,你可以定義either作爲參數化類型,這將允許name_of_num是多態的。這是否是一件好事取決於你想要解決的問題。

我不確定這是否解決了您的問題,但我希望它有幫助。

編輯

這裏的,如果你使用either類型的功能是什麼樣子。我會 使用int爲一種類型和string爲另一種。

type either = A of int | B of string 

let name_of_num list undefined_list len_undefined k = 
    if k < len_undefined then 
    (B (List.nth undefined_list k)) 
    else 
    (A (List.nth list (k - len_undefined))) 

val name_of_num : int list -> string list -> int -> int -> either = <fun> 
# 

編輯2

我感到那你可能需要使用異常來解決問題。如果您試圖填充映射值的矩陣,並且如果超出範圍的輸入很少(並且指示有錯誤),那麼當發現輸入錯誤時您可以引發異常。呼叫者可以捕捉異常並決定要做什麼。那麼你的name_of_num函數將總是返回xsd。 (如果它看到一個不好的值,它根本不會返回。)

+0

如果它永遠不會進入未定義列表?這種情況下可以有這個功能嗎? – Quyen 2012-02-20 03:02:52

+1

如果你的函數* always *從'list'返回一個元素,而永遠不會從'undefined_list'返回,那麼這個列表可以有兩種不同的類型,並且這個函數仍然可以很好的形成。但是這對我來說沒有多大意義。另外,編譯器必須能夠靜態地指出「undefined_list」從不使用。 – 2012-02-20 03:09:18

+0

'type any = A的Xsd.xsd | B的字符串' 'let name_of_num(xsds:'A list)(undefined:'B list)len_undefined k = if k Quyen 2012-02-20 04:03:36