【发布时间】:2014-05-31 23:22:35
【问题描述】:
OCaml 中有一个ignore 函数。
val ignore : 'a -> unit
丢弃其参数的值并返回()。例如, ignore(f x) 丢弃副作用函数 f 的结果。它 等价于 fx; (),但后者可能会产生一个 编译器警告;改写 ignore(f x) 可以避免警告。
我知道这个函数会做什么,但不明白使用它的意义。
谁能解释或举例说明我们何时必须使用它?
【问题讨论】:
标签: ocaml
OCaml 中有一个ignore 函数。
val ignore : 'a -> unit
丢弃其参数的值并返回()。例如, ignore(f x) 丢弃副作用函数 f 的结果。它 等价于 fx; (),但后者可能会产生一个 编译器警告;改写 ignore(f x) 可以避免警告。
我知道这个函数会做什么,但不明白使用它的意义。
谁能解释或举例说明我们何时必须使用它?
【问题讨论】:
标签: ocaml
你基本上回答了你自己的问题。你永远不必使用它。关键是要避免警告。如果你写f x; (),编译器会假设你可能做错了什么。可能您认为 f x 返回单位,因为您很少想忽略非单位值。
但是,有时情况并非如此,您真的想忽略非单位值。写ignore (f x) 记录了你知道f x 会返回一些东西但你故意忽略它的事实。
请注意,在实际代码中f x 可能更复杂,因此您对f x 的返回类型错误的可能性相当高。一个例子是部分应用。考虑f : int -> int -> unit。你可能不小心写了f 1,忘记了第二个参数,警告会帮助你。另一个例子是如果你执行open Async,那么标准库中的许多函数都会从返回单元变为返回unit Deferred.t。尤其是刚开始使用 Async 时,很可能会不小心认为分号运算符适用于真正需要使用 monadic bind 的地方。
【讨论】:
unit 之前写f x 没有意义,那么我无论如何都不会这样做;如果我不明白这一点,那么我可能会在() 之前写f x,我将无法考虑ignore 并使用它,好像我想在这里使用ignore 那样这是矛盾的首先到i don't understand that fact
let _ = f x in ()一样吗?
作为对 Ashish Agarwal 回答的补充(因为从您的评论来看,您似乎不太相信):
想象一下,我有一个具有副作用的函数,并返回一个值来指示有关计算的某些内容。然后,如果我对计算的过程感兴趣,我将需要它的返回值。但是,如果我不关心这一点,只是想产生副作用,我会使用ignore。
愚蠢的例子:假设你有一个函数对数组进行排序并根据数组的初始状态返回Was_already_sorted 或Was_not_sorted。然后,如果出于某种原因我想知道我的数组被排序的频率,我可能需要这个函数的返回值。如果没有,我会忽略它。
我同意这是一个愚蠢的例子。并且在许多情况下,可能有比使用忽略更好的方法来处理问题(我刚刚注意到我从不使用ignore)。如果您真的对此充满热情,您可以尝试在实际代码中找到使用此功能的示例(可能在 Unison 等软件的源代码中?)。
另外,请注意,您可以在同一端使用let _ = f x。
【讨论】: