是否可以让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/