我可以普遍量化 OCaml 函数中的 lambda 参数吗?

nam*_*sis 2 ocaml

我注意到我无法在 OCaml 中执行以下操作:

# let foo (f : 'a -> unit) = f 1; f "s";;
Run Code Online (Sandbox Code Playgroud)
Error: This expression has type string but an expression was expected of type
         int
Run Code Online (Sandbox Code Playgroud)

在 Haskell 中,可以通过使用 Rank2Types 普遍量化输入函数来解决这个问题f

{-# LANGUAGE Rank2Types #-}

foo :: (forall a. a -> ()) -> ()
foo f = let a = f 1 in f "2"
Run Code Online (Sandbox Code Playgroud)

我如何在 OCaml 中获得类似的体验?

oct*_*ron 7

OCaml 仅支持半显式高阶多态性:多态函数参数必须装箱在具有多态字段的记录内:

type id = { id: 'a. 'a -> 'a }
let id = { id=(fun x -> x) }
let f {id} = id 1, id "one"
Run Code Online (Sandbox Code Playgroud)

或在物体内部

let id' = object method id: 'a. 'a -> 'a = fun x -> x end
let f (o: <id:'a. 'a -> 'a>) = o#id 1, o#id "one"
Run Code Online (Sandbox Code Playgroud)

除了语法沉重之外,这种多态函数的显式装箱还具有以下优点:它可以很好地与类型推断配合使用,同时仍然只需要在记录类型或方法的定义中进行注释。