1

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

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”类型一起使用。

4

3 回答 3

1

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

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

于 2013-09-15T20:08:13.457 回答
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) ;;
于 2013-09-15T13:00:07.763 回答
1

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

if y == x then i

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

if y == x then i else ()

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

于 2013-09-16T11:11:16.633 回答