我在OCaml版本4.04的utop中定义了一个函数f。
utop # let f = function x -> x + 1;;
val f : int -> int = <fun>
当我试图忽略f时,我会遇到警告。
utop # let a = ignore (f : int -> int); f 2;;
Characters 15-19:
Warning 5: this function application is partial,
maybe some arguments are missing
val a : int = 3
触发警告5,因为ignore
后面的表达式具有函数接口int -> int
。
ignore (f 0)
和if false then (ignore f 0)
有效,但不优雅。我不想为f提供缺少的参数。除ignore
之外还有其他选择吗?
ignore
的动机在这个虚拟示例中并不十分清楚,但我确实需要使用它来避免在我的实际项目中出现其他警告。
感谢您的时间。
答案 0 :(得分:4)
非常粗略地说,形式e1; e2
的表达由OCaml typechecker处理如下:
e1
的函数类型为t -> t'
,则会发出警告5。e1
没有类型unit
,则会发出警告10。例如,
let f x =
prerr_endline "some side effect you may want";
(* but you may not want the returned function sometimes *)
fun y -> x + y
let a = f 1 2; f 1 2;; (* Warning 10 *)
let a = f 1; f 1 2;; (* Warning 5 *)
ignore e1; e2
的类型检查与e1; e2
的类型检查相同,只有一点:它会跳过第二次检查:即使e1
&#39,也不会发出警告10 ; s类型不是unit
。警告5的第一次检查仍在执行:
let a = ignore (f 1 2); f 1 2;; (* No warning *)
let a = ignore (f 1); f 1 2;; (* Warning 5 *)
所以ignore
旨在删除警告10,而不是5. ignore
的这种特殊处理是围绕OCaml源代码中is_ignore
的{{1}}函数定义编码的。< / p>
如果你想真的忽略警告5,我想到了两种方法:
typing/typecore.ml
第一个是使用与外卡匹配的模式。另一种是定义自己的忽略函数let a = let _ = f 1 in f 1 2;; (* No warning *)
let ignore' _ = ()
let a = ignore' (f 1); f 1 2;; (* No warning *)
。这是一个常见的OCaml函数,因此不执行发出上述警告5的ignore'
参数的特殊类型检查。
答案 1 :(得分:1)
您可以通过ignore
构造取代let _
来避免警告:
let a = let _ = (f : int -> int) in f 2;;
答案 2 :(得分:0)
您可以定义自己的忽略函数,该函数在箭头类型上运行,如下所示:
let ignore_fun (f:'a -> 'b) = ()
这样您就不再需要将参数传递给 f ,以下内容不会产生警告。
let a = ignore_fun (f : int -> int); f 2;;
答案 3 :(得分:0)
camlspotter的答案很好,你应该接受它。 我想添加第三个解决方案:将有问题的函数包装到元组中
let a = ignore (f,()); f 2;;
或列表
let a = ignore [f]; f 2;;
或任何你喜欢的东西。