OCaml 函数名称作为字符串

OCaml function name as string

有时我编写的函数会假设某些参数不会发生。如果他们这样做,这是一个错误,我失败了:

let foo = function
 | 0 -> ()
 | _ -> failwith "foo: bad argument"

如果我稍后重命名该函数,我必须记住也要更改字符串。有没有办法以更系统的方式做到这一点?我的思绪在

这样的解决方案上徘徊
| _ -> failwith (FUNCTION_NAME ^ ": bad argument")

其中 FUNCTION_NAME 是编译器或解释器将实例化的字符串变量。但我不知道这样的东西在 OCaml 中是否有效。如果没有,是否有最佳实践?

我认为您应该尽可能尝试使用更具体的类型,以便编译器可以防止您使用无效输入调用您的函数。 如果你真的找不到告诉类型系统你想要什么的方法,那就更努力地尝试,如果你真的做不到,那么使用 assert ,正如史蒂夫告诉你的那样,它会给你一些宝贵的调试信息(文件和行号比函数名更有用,因为你的函数很可能没有名字)。

有一组值可用于调试和错误报告。

引入了 OCaml 4.12 __FUNCTION__:

val __FUNCTION__ : string

__FUNCTION__ returns the name of the current function or method, including any enclosing modules or classes.

如果您不想按照@SteveVinoski 的建议使用 assert false,它们可能会有用。

__LOC__ : string
__FILE__ : string
__LINE__ : int
__MODULE__ : string
__POS__ : string * int * int * int

您还可以使用更高级的形式来包装表达式以确定其在源代码中的范围。

这些记录在 Stdlib 模块中。

从 4.12.0 开始,__FUNCTION__ 将 return 函数名称。

还有一些其他的debugging variables defined in Stdlib:

val __LOC__ : string
val __FILE__ : string
val __LINE__ : int
val __MODULE__ : string
val __POS__ : string * int * int * int
val __FUNCTION__ : string
val __LOC_OF__ : 'a -> string * 'a
val __LINE_OF__ : 'a -> int * 'a
val __POS_OF__ : 'a -> (string * int * int * int) * 'a