这是我第一次遇到以下警告 “警告 21:此语句永远不会返回(或类型不正确。)”而且我不知道如何解决它。
let display_committers_stats response = match response##readyState with
| XmlHttpRequest.DONE ->
begin match response##status with
| 200 ->
Js_client_ui.create_menu_tabs "GitSearchTabs";
let l =
Json_parser.get_commits (Js.to_string response##responseText) in
let values =
Json_parser.group_commits_by_user l
|> List.map (fun (author, commits) ->
Js_data.create_discreteBar_item author (float_of_int commits))
|> Array.of_list
|> Js.array in
let discreteBar_chart =
Js_data.create_discreteBar_chart "Commits-impact" values in
let js_arr = Js.array ([|discreteBar_chart |]) in
Js.Unsafe.fun_call
(Js.Unsafe.variable "create_discreteBar_chart")
[|
Js.Unsafe.inject ((js_arr))
|];
let js_arr =
l
|> List.mapi (fun i commit ->
Js_data.create_timeline_data i commit.Git_data.message
commit.Git_data.time)
|> Array.of_list
|> Js.array in
Js.Unsafe.fun_call
(Js.Unsafe.variable "create_timeline")
[|
Js.Unsafe.inject ((js_arr))
|]
| _ -> Printf.printf "Unexcepted status\n" end
| _ -> Printf.printf "Unexcepted state\n"
警告显示以下行:
Js.Unsafe.fun_call
(Js.Unsafe.variable "create_discreteBar_chart")
[|
Js.Unsafe.inject ((js_arr))
|];
对于在 Ocaml 中执行多个表达式,我知道问题是使用 ;在表达式之间,但现在我的函数有什么问题?我可以给点建议吗?
最佳答案
尝试将调用包含在 ignore
中,即代替 Js.Unsafe.fun_call ...;
, ignore (Js.Unsafe.fun_call ...);
.
发生这种情况的原因是您的 JS 函数调用具有结果类型“'b
”,它不依赖于任何参数类型。在 OCaml 类型系统中,这通常意味着函数不会返回,因为“产生”任意类型值的唯一方法 'b
从无到有就是提出一个异常(exception)——也就是说,放弃试图产生它。
序列表达式(分号)e1; e2
表示完成第一个表达式,然后完成第二个表达式。在这种情况下,OCaml 担心您的 e1
(JS 函数调用)由于其不受约束的结果类型而无法完成,如上所述。这将使序列表达式毫无意义,这就是您收到警告的原因。但是,我们知道原因e1
具有不受约束的结果类型不是因为它没有完成,而是因为我们使用了对 JS 的不安全绑定(bind)。
要解决这个问题,请包装 e1
调用ignore
,这是一个接受任何东西并计算为单位的函数。现在,;
会“看到”unit
在其左侧,而不是不受约束的 'b
.
一般来说,你总是希望有一个 unit
类型的表达式。在 ;
的左侧.因此,即使您有一个计算结果为受约束类型的表达式(例如具体类型 int
或参数类型中提到的类型参数),如果该类型不是 unit
,您仍应将该表达式包含在 ignore
中.
关于ocaml - 避免警告 "Warning 21: this statement never returns (or has an unsound type.)",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31278561/