问题的根源在于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 ...
上给出同样的错误。
这让我非常困惑,并提出以下问题:
let make ...
上的类型注释完全被忽略?注意:我使用的是BuckleScript,它位于4.02.3上。在线游乐场here。
答案 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?)