我正在尝试在下面的 OCaml 中编写一个简单的可执行代码。
open Printf
open Lwt
open Cohttp
open Cohttp_lwt_unix
open Yojson
let () =
let ip = "8.8.8.8" in
let key = "" in
let uri =
Uri.of_string
("https://api.ip2location.io/?format=json&key=" ^ key ^ "&ip=" ^ ip)
in
Lwt_main.run
( Client.get uri >>= fun (resp, body) ->
let code = resp |> Response.status |> Code.code_of_status in
let json_promise = body |> Cohttp_lwt.Body.to_string in
json_promise >>= fun json_string ->
let json = Basic.from_string json_string in
let open Yojson.Basic.Util in
if code == 200 then
if member "usage_type" json <> `Null then
let usage_type = json |> member "usage_type" |> to_string in
printf "usage_type: %s\n" usage_type
else
printf
"ERROR: The usage_type field requires a paid subscription to the \
Starter plan or higher."
else if (code == 400 || code == 401) && member "error" json <> `Null then
let error_message =
json |> member "error" |> member "error_message" |> to_string
in
printf "ERROR: " ^ error_message
else printf "HTTP Code: " ^ Int.to_string code )
但是当我跑步时,我一直看到下面的内容
dune build
。
File "bin/main.ml", line 24, characters 10-46:
24 | printf "usage_type: %s\n" usage_type
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This expression has type unit but an expression was expected of type
'a Client.io
从其他 StackOverflow 帖子来看,它似乎与
if/else
中返回的不同类型有关,但我已确保所有 if/else
都使用 printf
。
如果有人能让我知道我还做错了什么,我将不胜感激。
我怀疑这是由于
>>=
造成的,其 Lwt 中的类型是
(>>=) : 'a Lwt.t -> ('a -> 'b Lwt.t) -> 'b Lwt.t
在左侧,您将
Client.get url
的结果传递给它,因此右侧必须是返回相同类型的函数。同样,Lwt.run
期望 Lwt.t
。 (我不太熟悉所有涉及的库,但 Client.io
可能是一个类型同义词,在这里扩展为 Lwt.t
。)
此示例的修复方法应该是使用
>|=
而不是第二个 >>=
,其类型为
(>|=) : 'a Lwt.t -> ('a -> 'b) -> 'b Lwt.t