简单的OCaml类型错误

3

功能说明:

编写一个函数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

我不知道为什么当我将“l”标记为“int list”时,Ocaml会在“0”处出现问题。如果有人能帮我解决这个问题,我将非常感激!谢谢!

2
请使用 List.mem - Anton Trunov
2个回答

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' ,但是您尝试使用 'int' (类型)来提供该参数。因此,类型系统正在尝试统一 'int' 和 'a list' ,但并不存在这样的 'a' ,使得 'int = a list' ,因此它不能通过类型检查。因此,您需要传递一个函数,或者像 Anton 建议的那样使用 'List.mem' 函数。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接