types - OCaml详细类型错误

标签 types compiler-errors ocaml

是否可以让OCaml显示有关类型错误的更多详细信息。例如

Error: This expression has type AAAAA
       but an expression was expected of type BBBBB

有时我会花费大量精力试图找出哪些晦涩的声明期望BBBBB导致此类错误。如果它可以显示有问题的行,那就太好了。

最佳答案

对的,这是可能的。但是您需要与编译器进行一些协作,然后它将在更友好的错误中响应您。因此,您的问题的答案是-使用类型注释。注释表达式时,可以为编译器提供有关意图的更多信息。然后,编译器可以向您显示更接近实际故障点的错误。

例:

您拥有一个可以进行类型检查的功能,但其中包含一个错误:

let run sum n lst = 
    List.fold ~init:(sum,n)
              ~f:(fun (s,n) x -> s + x, n + 1)

稍后,您尝试使用它,它向您洒出一个奇怪的错误:
let average lst =
    let (sum,n) = run 0 0 lst in
    sum / n;;
    Characters 36-47:
      let (sum,n) = run 0 0 lst in
                    ^^^^^^^^^^^
Error: This expression has type int Core_kernel.Std.List.t -> int * int
       but an expression was expected of type 'a * 'b

因此,您遇到了麻烦,需要调查问题。您开始添加注释,本质上是向编译器解释您的意图。一段时间后,您将返回run的定义并添加注释:
let run sum n lst : int * int = 
    List.fold ~init:(sum,n)
              ~f:(fun (s,n) x -> s + x, n + 1)

并发现实际错误在此函数内。

因此,有一些规则可以帮助您从编译器中获取更多有用的错误:
  • 注释顶级表达式(如果不想指定它们,可以省略一些细节,这样代码仍然可读。例如,可以代替(very * complex types) list编写'a list('a, 'b types) list。请注意,此处'a'b并不代表多态类型变量,这只是对编译器说的一种方式:“哦,我真的不知道,或者不在乎它们代表什么,只要随便用您想要的内容填充它即可”,换句话说,您不必限制此类型的类型检查器)。
  • 始终注释通配符。如果您有这样的事情:

    让_ = List.fold ...

  • 然后确保此通配符实际上代表您对它们的想法:
    let _ : int option = List.fold ...
    
  • 使用merlin。它可以让您在创建错误的那一刻(而不是几小时后)内捕获错误。

  • 最后一句话:OCaml typechecker只是一个约束求解器,如果您给它提供一组详细的约束,它将给您返回详细的答案。否则,输入错误会给您带来不良的输出。

    关于types - OCaml详细类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26991224/

    相关文章:

    javascript - 对象不会被创建?

    tuples - OCaml中有pair构造函数吗?

    ocaml - 使用 Ocamllex 对字符串进行词法分析(The Tiger Compiler)

    asp.net - 我应该如何检测 ASP.NET 中上传文件的 MIME 类型?

    scala - Scala 中具有依赖类型的参数的模式匹配的类型安全性

    c++ - 使用 CMake 和 C++ 处理共享库依赖

    c# - 为什么在构建期间出现此错误?提到一些有关无法调试的信息

    c++ - 究竟为什么编译器直到运行时才能确定变量的真实类型?

    types - Idris 中是否存在宇宙不一致的重要示例?

    performance - 迭代速度最快的标准 OCaml 数据结构是什么?