简单的ocaml类型错误

时间:2016-09-09 13:03:43

标签: ocaml typeerror

功能规格:

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

时才返回true

代码:

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

错误:

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

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

谢谢!

2 个答案:

答案 0 :(得分:3)

首先,您没有将l标记为int list,语法为:

let any_zeroes l: int list

表示any_zeroes是一个返回int list的函数。注释它的正确方法如下:

let any_zeroes (l : int list) : bool

其次,你标记的事实不会改变程序的语义。它是一种类型约束,它告诉类型推断系统,您希望将此类型统一到您指定的任何类型。如果类型检查程序无法执行此操作,则会因错误而挽救。并且类型检查器不需要您的约束,它们大多是为了可读性而添加的。 (我认为你所参加的课程也需要它们)。

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

答案 1 :(得分:1)

类型注释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