优雅地忽略OCaml中的一个功能

时间:2017-08-14 10:53:33

标签: ocaml

我在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的动机在这个虚拟示例中并不十分清楚,但我确实需要使用它来避免在我的实际项目中出现其他警告。

感谢您的时间。

4 个答案:

答案 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;;

或任何你喜欢的东西。