OCaml:查找特定类型的值

OCaml:查找特定类型的值,ocaml,static-typing,Ocaml,Static Typing,我有一些值的列表,我需要找出哪种值是第一个: 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 l

我有一些值的列表,我需要找出哪种值是第一个:

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 *)
    )
;;
是否有一种方法可以在不触碰find_first中所有类型的MyType的情况下执行此操作-是否可以比较两个值的类型?
谢谢。

您发布的代码无法编译,但我认为您正在查找以下信息:

  • 可以编写所谓的or模式,例如,
    (函数MAlpha | MBeta->…)

  • 但模式不是一流公民。您不能从列表中构建模式(顺便说一句,
    [MGamma,MAlpha,MBeta]
    是您的问题中没有编译的内容之一),也不能将模式作为参数传递给函数

  • 但是,您可以构建并传递与模式匹配的函数,因此如果您愿意将函数
    find_first
    更改为使用函数,而不是
    what
    的列表,则使用起来会更方便


  • 另一种看待这一点的方式是,你的类型有一个等价关系;i、 例如,在某些地方,您希望对所有
    MAlpha
    s进行相同的处理,对所有
    MBeta
    s进行相同的处理,对所有
    MGamma
    s进行相同的处理。等价关系的标准处理方法是选择一个代表整个等价值集(等价类)的代表元素

    在您的例子中,您可以使用
    MAlpha
    来表示所有
    MAlpha
    s(但只有一个),
    MBeta[]
    来表示所有
    MBeta
    s和
    MGamma(“,0)
    来表示所有
    MGamma
    s。您可以使用一个函数从给定值计算代表值:

    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
    mbeta
    mgamma
    进行模式匹配。你必须和他们做平等比较

    您可能希望在列表中找到特定的值,而不是规范化的值。我认为这个案子的变化应该很清楚

    这也回答了你问题的第二部分。
    List.find
    功能在找到所需内容后将立即停止

    OCaml为不包含函数值的所有类型定义一个排序关系。如果这种内置(多态)排序不能满足您的需要,您必须定义自己的排序。您当然需要这样做来比较两种不同类型的值;但那不是你在这里做的


    如果列表中没有与您所说的内容相似的元素,此版本的
    find_first
    将引发异常
    Not_found
    。这是另一个需要考虑的问题。

    你所说的
    列表是什么意思。创建
    ,为什么还要给它另外两个名字?@PascalCuoq,修正了这个问题。所以,我有where-to-find,需要知道what-to-find中显示的类型首先存储在where-to-find中。这正是我想要的!非常感谢。我想我没有解释清楚,抱歉。很难用OCaml的术语来思考类似C语言的语言。我甚至无法编写编译示例:)