首页 文章

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

提问于
浏览
1

问题的根源在于 external

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

我需要使用任何类型的:

let debug = make "name:space:a"

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

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

此表达式的类型为int,但表达式的类型为string

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

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

这当然会导致错误:

此定义的类型为'a - >单位,不如'a0 . 'a0 - >单位

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

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

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

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

  • 是否真的无法定义具有多态类型的外部?

  • 无论1的答案如何,为什么不能使用外部的显式多态类型注释?

  • 为什么 let make ... 上的类型注释完全被忽略?

注意:我使用的是BuckleScript,它位于4.02.3上 . 在线游乐场here .

1 回答

  • 4

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

    您对 debug 的定义是一个函数应用程序,因此它不能一般化(多态) .

    解决方案是进行eta扩展:

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

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

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

相关问题