问题的根源在于 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 回答
这是 Value 限制,而不是使用
external
的结果 . (以前的讨论,其中之一:The value restriction . )您对
debug
的定义是一个函数应用程序,因此它不能一般化(多态) .解决方案是进行eta扩展:
现在你对
debug
的定义是一个lambda,可以推广 .(之前关于eta扩展的讨论:Why does OCaml sometimes require eta expansion?)