在列表中查找第一个匹配项

时间:2013-09-15 12:24:17

标签: ocaml caml

我想找到列表中第一个出现的数字:

let pos_list = function (list , x) -> 
   let rec pos = function 
    |([] , x , i) -> i
    |([y] , x , i) -> if y == x then i
    |(s::t , x , i) -> if s == x then i else pos(t , x , i + 1) in pos(list , x ,  0) ;;

但是编译器抱怨表达式是“uint”类型,而是用“int”类型。

3 个答案:

答案 0 :(得分:1)

从模式匹配中删除第二种情况。此案例已与最后一个s = y, t = []匹配。所以函数可以简化为

let pos_list (list, x) =
    let rec pos = function 
    | ([], x, i) -> i
    | (s::t, x, i) -> if s == x then i else pos(t, x, i + 1) in pos(list, x, 0) ;;

答案 1 :(得分:1)

为什么使用==(物理相等)而不是结构相等的=?我意识到,如果你只有整数,这可能不会产生影响,但它可能会产生意想不到的行为。

请参阅文档中的比较部分:http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html

答案 2 :(得分:1)

Pavel Zaichenkov的答案当然是最好的答案,但您可能有兴趣了解错误的确切原因。即,当你有

if y == x then i

没有相应的else表达式,整个表达式被视为

if y == x then i else ()

其中()是类型unit(而不是uint)的唯一值,这是仅针对其副作用进行评估的表达式类型。由于if的两个分支必须具有相同的类型,因此i也被视为具有unit类型。然后,在对模式匹配的第三个分支进行类型检查时,您尝试添加i1,这意味着i应该具有类型int,因此类型错误。