Ocaml 什么是不健全类型?
最近我得到了密码Ocaml 什么是不健全类型?,ocaml,Ocaml,最近我得到了密码 List.fold_left (fun acc x -> raise x ; acc) 3 我完全同意这个部分应用程序有一个函数 类型exn list->int的值,以及它产生警告的事实 这并不奇怪。然而,我不确定警告的一半是什么 指: 警告21:此语句永远不会返回(或类型不正确。) 实际上,我找不到与此警告无关的任何参考 非返回语句的结果。甚至只有ocamlc的手册页 提及此警告的非返回语句,以及warnings.ml 仅将其称为不返回\u语句 我熟悉稳健性的概念,
List.fold_left (fun acc x -> raise x ; acc) 3
我完全同意这个部分应用程序有一个函数
类型exn list->int
的值,以及它产生警告的事实
这并不奇怪。然而,我不确定警告的一半是什么
指:
警告21:此语句永远不会返回(或类型不正确。)
实际上,我找不到与此警告无关的任何参考
非返回语句的结果。甚至只有ocamlc的手册页
提及此警告的非返回语句,以及warnings.ml
仅将其称为不返回\u语句
我熟悉稳健性的概念,因为它与类型有关
系统,但一种类型本身就不健全的想法似乎
我觉得奇怪
因此,我的问题是:
什么是不健全的类型
在什么情况下,当OCaml
只会发出警告而不是彻底失败
有人发布了这个问题,当我写答案时,它被删除了。我相信这个问题很有趣,值得转载。请考虑你可能有人愿意帮助你:-(报告21的警告)
首先,让我们考虑返回不相关的'a
的函数:我这里不是指像let id x=x
这样的函数,因为它有'a->'a
类型,返回类型'a
与输入相关。我指的是像raise:exn->'a
和exit:int->'a
这样的函数
这些函数返回不相关的'a
被认为永远不会返回。因为类型'a
(更准确地说,a)没有公民。函数只能终止程序(退出或引发异常)或陷入无限循环:让rec循环()=循环()
当语句类型为'a
时,会提到警告21(实际上还有另一个条件,但为了简单起见,我跳过了)。例如
# loop (); print_string "end of the infinite loop";;
Warning 21: this statement never returns (or has an unsound type.)
这是警告21的主要目的。那么,后半部分是什么
“不健全类型”
即使语句实际返回某些内容,也可以报告警告21。在这种情况下,警告消息表明该语句的类型不正确
为什么不合理?因为表达式确实为所有“a.”a返回类型为的值,该值没有公民。它打破了OCaml所依赖的类型理论的基础
在OCaml中,有几种方法可以编写类型不合理的表达式:
使用Obj.magic
。它拧紧类型系统,因此您可以编写类型为'a
的表达式,该表达式返回:
(Obj.magic 1); print_string "2"
使用external
。与Obj.magic
相同,您可以为任何外部值和函数指定任意类型:
external crazy : unit -> 'a = "%identity"
let f () = crazy () (* val f : unit -> 'a *)
let _ = f (); print_string "3"
对于OCaml类型系统,不可能区分非返回表达式和类型不正确的表达式。这就是为什么它不能将不正确的事情排除在错误之外。跟踪定义来判断语句是否类型不正确通常也是不可能的,即使可能,也要花费很多钱。我相信这个问题是有问题的移动是因为它是的副本,其中警告是由使用外部(js_of_ocaml)引起的具有无约束结果类型的函数–如下面的答案所示。我怀疑提问者是刚刚在已接受的答案上给了我+1的那个人。当然,这里的焦点有点不同。我是问/删除该问题的人;我只是发现了(呵呵)这个。@antron说的正是我删除它的原因。是的,+1是我写的。;)回答得好。为了完整起见,您可能希望将解分组(input\u value
和marshall.from.*
)作为不可靠的函数。(事实上,我认为它们比Obj.magic
更有用,特别是对于那些不是类型系统专家的人来说)。