我在文本文件mpd.ml中有一个简单的模块,其中包含变体类型:
type ack_error =
| Not_list
| Arg
| Password
| Permission
| Unknown
| No_exist
| Playlist_max
| System
| Playlist_load
| Update_already
| Player_sync
| Exist
type response = Ok | Error of (ack_error * int * string * string)当我使用它们时:
let test_ok test_ctxt = assert_equal Mpd.Ok (Mpd.parse_response "OK\n")即使一切正常,我也有这样的警告:
ocamlfind ocamlc -o test -package oUnit,str -linkpkg -g mpd.ml test.ml
File "test.ml", line 7, characters 2-4:
Warning 40: Ok was selected from type Mpd.response.
It is not visible in the current scope, and will not
be selected if the type becomes unknown.
File "test.ml", line 8, characters 2-7:
Warning 40: Error was selected from type Mpd.response.
It is not visible in the current scope, and will not
be selected if the type becomes unknown.这意味着什么,以及如何改进我的代码,使这些警告无效。
编辑**
完整代码:https://gist.github.com/cedlemo/8806f367a971bacfaa0f59b1c78a3605
发布于 2016-09-12 13:24:38
看上去你不是在显示台词,而是因为这引起了警告。正如在警告中所说的,Ok构造函数在字符2-4之间,但是代码中没有类似的地方。
通常,我建议使用IDE,如Emacs、Vim等,因为它们将直接跳转到错误的源头。
由于这个警告是相当普遍的,我仍会解释其背后的理由。在OCaml中,构造函数和字段名是标识符,它以及任何其他标识符都有作用域,而作用域就是模块。因此,无论何时定义变体类型,实际上都是在模块范围内定义几个构造函数。要引用构造函数,您需要使用一个完全限定的名称,或者确保它在作用域中。如果您在模块中,这定义了它,那么您就没事了,否则您需要以某种方式将名称带到作用域中。
在以前版本的OCaml中,使用构造函数是一个错误,它不在作用域中。只是一个普通的未绑定标识符。最迟的是,添加了启发式,从而推断构造函数来自哪个范围。但是它仍然受到警告的保护,所以人们实际上是在尽量不使用它。(离题了,我想知道为什么人们会添加一个特性,然后暂时用警告来羞辱它,所以没有人会真正使用它)。
因此,要修复警告,需要用模块名称限定所有构造函数,或者打开模块将所有定义带到作用域,例如open Mpd。
更新
因此,代码完整代码显示,在第7行,正如编译器所指出的那样,有一个不合格的构造函数:
match response with
| Ok -> false
| Error ...在这里,Ok是不合格的,正确的方法是说:
match response with
| Mpd.Ok -> false
| Mpd.Error ...描述我特别使用的策略的一般建议是定义一个只定义类型的模块,以便您可以相当安全地打开它。这还将解决在.mli中重复类型定义的问题,因为不为只定义类型的模块提供.mli文件是可以接受的。
https://stackoverflow.com/questions/39451038
复制相似问题