ocaml - 如何强制 OCaml 推断出更通用的类型?

标签 ocaml

我想定义一个接受可选参数的函数,该参数是一个函数 ('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表达路径就不健全。换句话说,取决于是否 fNoneSome 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/

相关文章:

haskell - SystemT 编译器和处理 Haskell 中的无限类型

f# - 在 F# 中通过组合定义 EntryPoint

exception - 使用异常中断对文件行的迭代

ocaml - “B”是什么意思?

haskell - GADT 提供了什么是 OOP 和泛型无法做到的?

algorithm - 计划生育作业。是否可以使用嵌套模式匹配而不是辅助函数来定义函数?

debugging - 将 OCaml 转换为 F# : Is there a simple way to simulate OCaml top-level #trace in F#

ocaml - 为什么 OCaml 中的 Peano 数字由于范围错误而无法正常工作?

types - 在定义它们的模块之外使用开放联合

ocaml - 带有可选参数的 Printf 错误