2011-09-24 78 views
2

的價值,我有一些價值觀,我需要找出名單哪種值是第一:OCaml的:尋找特定類型的

type my_types = 
    | MAlpha 
    | MBeta of int list 
    | MGamma of string * int 

let find_first where what = 
    List.iter (fun m -> 
     | MAlpha -> 
      (* iterate frough "what" to find if it was asked to look and return it if it was *) 
     | (* do the same for all other types *) 
    ) where; 
;; 

let main = 
    let where_to_find = [MGamma, MAlpha, MBeta] in 
    let what_to_find = [MAlpha, MBeta] in 
    (match (first_found where_to_find what_to_find) with 
    | MAlpha -> 
     (* should return this *) 
    ) 
;; 

有沒有辦法這樣做不接觸各類MyTypefind_first - 是否可以比較兩個值的類型? 謝謝。

+0

你是什麼意思的'List.create',你爲什麼給它兩個其他的名字? –

+0

@PascalCuoq,修正了這個問題。所以,我有** where_to_find **,並且需要知道** what_to_find **首先存儲在** where_to_find **中的哪個類型。 – Slav

回答

3

另一種方法來看待這種情況是,你有你的類型的等價關係;也就是說,你有一些地方要處理所有的MAlpha s,所有的MBeta都是一樣的,並且所有的MGamma都是一樣的。等價關係的標準處理是挑選一個代表整個等價值集(等價類)的代表性元素。

你的情況,你可以使用MAlpha代表所有MAlpha S(但只是其中之一),MBeta []代表所有的MBeta S和MGamma ("", 0)代表所有MGamma秒。你將有一個函數從給定的一個計算代表值:

let malpha = MAlpha 
let mbeta = MBeta [] 
let mgamma = MGamma ("", 0) 

let canonicalize = 
    function 
    | MAlpha -> malpha 
    | MBeta _ -> mbeta 
    | MGamma _ -> mgamma 

let find_first where what = 
    canonicalize (List.find (fun x -> List.mem (canonicalize x) what) where) 

let main() = 
    let where_to_find = [MGamma ("a", 3); MAlpha; MBeta [3; 4]] in 
    let what_to_find = [malpha; mbeta] in 
    try 
     let found = find_first where_to_find what_to_find 
     in 
      if found = malpha then (* what to do *) 
      else if found = mbeta then (* what to do *) 
      else (* what to do *) 
    with Not_found -> (* nothing was there *) 

我寫這樣的代碼,它不出來太糟糕了。在你的情況下,它允許你自然地指定what參數。但是,一個缺點是,您無法與malpha,mbetamgamma進行模式匹配。你必須對他們進行平等比較。

可能是因爲您想要在列表中找到特定值,而不是標準化的值。我認爲這種情況下的變化應該很清楚。

這也回答了你的問題的第二部分。 List.find函數一旦找到它所要查找的內容就會停止。

OCaml爲所有不包含函數值的類型定義了一個排序關係。如果這種內置(多態)排序不能達到你想要的,你必須定義你自己的。您肯定需要這樣做來比較兩種不同類型的值;但這不是你在這裏做的。

如果列表中沒有看起來像您所說的那樣的元素,則此版本的find_first將引發異常Not_found。這是別人想的。

+0

這正是我想要的!謝謝! – Slav

4

你已經張貼不會編譯代碼,但我認爲你正在尋找的以下信息:

  1. 它可以編寫所謂的或圖案,如,例如,(function MAlpha | MBeta _ -> ...)

  2. 但模式不是一流的公民。你不能從列表中構建一個模式(順便說一句,[MGamma, MAlpha, MBeta]是你的問題中沒有編譯的東西之一),你也不能將模式作爲參數傳遞給函數。

  3. 但是,你可以建立並通過周圍的模式匹配功能,所以如果你願意改變你的函數find_first採取的函數,而不是爲what列表,它使用起來會更加方便。

+0

我想我沒有解釋它很好,對不起。在C語言之後很難用OCaml的話來思考。我甚至無法編寫編譯示例:) – Slav