我有一个使用Unix lib作为其时间函数的函数:
let rfc822 (t: Unix.tm) : string =
Printf.sprintf "%s, %s %s %d %s:%s:%s %s"
(List.nth short_days t.tm_wday)
(padInt t.tm_yday 2 "0")
(List.nth short_month t.tm_mon)
(t.tm_year + 1900)
(padInt t.tm_hour 2 "0")
(padInt t.tm_min 2 "0")
(padInt t.tm_sec 2 "0")
"GMT"
我收到了这个警告:
ocamlbuild -libs unix,str -Is recore/src,ostd/src,owebl/src app.native
+ /usr/bin/ocamlc -c -I recore/src -I ostd/src -I owebl/src -o recore/src/time.cmo recore/src/time.ml
File "recore/src/time.ml", line 45, characters 27-34:
Warning 40: tm_wday was selected from type Unix.tm.
It is not visible in the current scope, and will not
be selected if the type becomes unknown.
File "recore/src/time.ml", line 46, characters 14-21:
Warning 40: tm_yday was selected from type Unix.tm.
It is not visible in the current scope, and will not
be selected if the type becomes unknown.
File "recore/src/time.ml", line 46, characters 4-28:
Error: This expression has type 'a -> string
but an expression was expected of type string
Command exited with code 2.
Compilation unsuccessful after building 13 targets (12 cached) in 00:00:00.
Makefile:8: recipe for target 'old' failed
make: *** [old] Error 10
我该如何处理此警告?如果可能的话,我宁愿避免open
Unix模块。
(请忽略实际的编译错误。)
答案 0 :(得分:5)
您可以撰写t.Unix.tm_yday
$ ocaml
OCaml version 4.02.1
# let f (t: Unix.tm) = t.tm_yday;;
Warning 40: tm_yday was selected from type Unix.tm.
It is not visible in the current scope, and will not
be selected if the type becomes unknown.
val f : Unix.tm -> int = <fun>
# let f (t: Unix.tm) = t.Unix.tm_yday;;
val f : Unix.tm -> int = <fun>
<强>更新强>
要在文档中找到它,您需要查找field
:
field ::= [ module-path . ] field-name
字段名称可以包含字段名称本身之前的模块名称(或嵌套模块的模块名称序列)。
更新2
还有两种用于在本地打开模块的语法。对于这个微小的功能来说,它们看起来有些过分,但对于更复杂的功能来说可能更整洁。模块的符号可在整个子表达式中直接使用。
$ ocaml
OCaml version 4.02.1
# let f t = Unix.(t.tm_yday);;
val f : Unix.tm -> int = <fun>
# let f t = let open Unix in t.tm_yday;;
val f : Unix.tm -> int = <fun>
这些在Local opens中记录为语言扩展。