简单的ocaml类型错误

Simple ocaml type error

函数说明:

编写一个函数 any_zeroes : int list -> bool 当且仅当输入列表包含至少一个 0

时 returns 为真

代码:

let any_zeroes l: int list = 
    List.exists 0 l

错误:

This expression has type int but an expression was expected of type
         'a -> bool

我不知道为什么当我将 l 标记为 int list 时 Ocaml 对 0 有问题。如果有人能帮我解决这个问题,我将不胜感激!

谢谢!

所以,首先,你没有将l标记为int list,语法:

let any_zeroes l: int list

表示any_zeroes是函数,表示returns是int list。正确的注释方法如下:

let any_zeroes (l : int list) : bool

其次,事实上,您 标记 某些东西不会改变程序的语义。它是一个类型约束,它告诉类型推理系统,您希望此类型统一到您指定的任何类型。如果类型检查器不能做到这一点,它将因错误而退出。并且类型检查器不需要您的约束,它们主要是为了可读性而添加的。 (我认为您正在学习的课程也需要它们)。

最后,错误指向的不是 l(如您所想,已注释),而是指向 0。该消息告诉您,List.exists 函数正在接受类型为 'a -> bool 的函数作为第一个参数,但您正试图向它提供类型为 [=21= 的 0 ].所以,类型系统试图统一int'a list,并没有int = 'a list这样的'a,所以它不进行类型检查。所以你要么需要传递一个函数,要么像 Anton 所建议的那样使用 List.mem

类型注解let any_zeroes l: int list = ...表示any_zeroes l的类型是int list;这不是你的意思。

与您的规范相关的正确类型注释是:

let any_zeroes 
: int list -> bool 
= fun l -> List.exists 0 l

在顶层,反馈:

= fun l -> List.exists 0 l;;
                       ^
This expression has type int but an expression was expected of type
     'a -> bool

确实,由于 List.exists 的类型,此表达式无法进行类型检查:

# List.exists;;
- : ('a -> bool) -> 'a list -> bool = <fun>

第一个参数是谓词,0 不是。 正确的实现是:

let any_zeroes 
: int list -> bool 
= let is_zero x = x = 0 in
  fun l -> List.exists is_zero l