【问题标题】:Simple ocaml type error简单的 ocaml 类型错误
【发布时间】:2016-09-10 19:13:39
【问题描述】:

功能说明:

编写一个函数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 有问题。如果有人能帮我解决这个问题,我们将不胜感激!

谢谢!

【问题讨论】:

  • 改用List.mem

标签: ocaml typeerror


【解决方案1】:

所以,首先,你没有将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 类型的函数作为第一个参数,但您尝试使用 0 类型为 int 的函数提供它。所以,类型系统试图统一int'a list,没有'aint = 'a list这样的int = 'a list,所以不进行类型检查。因此,您要么需要传递一个函数,要么按照 Anton 的建议使用 List.mem

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2016-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2017-07-15
      • 2016-01-17
      • 1970-01-01
      相关资源
      最近更新 更多