在外部强制执行多态类型变量

时间:2017-10-24 03:36:17

标签: types polymorphism ocaml external ffi

问题的根源在于external

external make : string -> 'a -> unit = "debug"

我需要使用任何类型:

let debug = make "name:space:a"

let _ = debug "log this thing"
let _ = debug 42

不幸的是,这导致最后一行出现以下错误:

  

此表达式的类型为int,但表达式的类型为字符串

所以我需要使type参数显式多态,但从我可以理解的是,这可以出于某种原因只能在附加到let绑定的类型注释中完成。将其添加到外部会产生语法错误。所以我试试:

let debug : 'a. 'a -> unit = make "name:space:a"

当然会导致错误:

  

此定义的类型为' a - >不是一般的单位,而不是' a0。 ' a0 - >单元

所以我尝试了另一种欺骗系统的方法,然后在external之后添加:

let make : 'a. string -> 'a -> unit = make

令我惊讶的是,这行没有给出类似的类型错误,但似乎只是忽略了类型注释,并继续在let debug ...上给出同样的错误。

这让我非常困惑,并提出以下问题:

  1. 是否真的无法定义具有多态类型的外部?
  2. 无论1的答案如何,为什么不能使用外部的显式多态类型注释?
  3. 为什么let make ...上的类型注释完全被忽略?
  4. 注意:我使用的是BuckleScript,它位于4.02.3上。在线游乐场here

1 个答案:

答案 0 :(得分:4)

这是价值限制,而不是使用external的结果。 (之前的讨论,其中之一:The value restriction。)

您对debug的定义是一个函数应用程序,因此不能一概而论(多态)。

解决方案是进行eta扩展:

let debug x = make "name:space:a" x

现在你对debug的定义是一个lambda,可以推广。

(之前关于eta扩展的讨论:Why does OCaml sometimes require eta expansion?