2011-09-24 41 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