我想定义一个接受可选参数的函数,该参数是一个函数 ('a -> 'b)。默认值应该是身份,实际上是 ('a -> 'a)
,但我认为没有理由它不应该与更通用的 ('a -> 'b)
。当我尝试时:
let optional_apply ?f i =
match f with
| None -> i + 4
| Some fn -> fn (i + 4)
我总是得到窄类型?f:(int -> int) -> int -> int
。但我想将 f 保留为 int -> 'b
。我能做些什么?或者这只是不合理的,因为 optional_apply
没有明确的类型?如果是这样,我如何获得类似的功能?
最佳答案
这是不可能的,f
参数不能是可选的。一个简单的解释是,可选参数只是一个语法糖。
因此,如果没有糖,您的函数可以重写为以下形式:
let optional_apply f n = match f with
| Some f -> f (n + 4)
| None -> (n + 4)
这里类型检查器只允许我们使用 f
的一种类型。 :int -> int
。如果它允许我们 int -> 'a
键入,然后输入 None
表达路径就不健全。换句话说,取决于是否 f
是 None
或Some
optional_apply
将评估不同的类型。这被认为是不合理的。
证明不健全的最好方法是给出一个简单的例子,其中类型检查器将允许不健全的程序:
let f = ref None
let g n = optional_apply ?f:!f n
使用此定义,如果类型检查器允许 f
参数保持多态性,那么我们可以随时“打破”g
通过改变 f
来实现功能引用其他任何东西。
关于ocaml - 如何强制 OCaml 推断出更通用的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28267730/