该表达式的类型为字符串 t,但表达式应为字符串类型

Vla*_*lam 1 ocaml

我是 OCaml 新手,所以这对你们中的一些人来说可能是显而易见的,但希望你们能对我有耐心。

在我的代码顶部,我有这些:

open Lwt
open Cohttp
open Cohttp_lwt_unix
Run Code Online (Sandbox Code Playgroud)

然后我有以下代码:

let call_api config ip add_on lang =
  let protocol = if config.use_ssl then "https" else "http" in
  let uri = Uri.of_string (protocol ^ "://api.example.com/v2/?key=" ^ config.api_key ^ "&ip=" ^ ip ^ "&package=" ^ config.api_package ^ "&addon=" ^ add_on ^ "&lang=" ^ lang) in
  
  Lwt_main.run begin
    Client.get uri >>= fun (resp, body) ->
    let code = resp |> Response.status |> Code.code_of_status in
    let json = body |> Cohttp_lwt.Body.to_string in
    printf "JSON: %s\n" (json);
   (code, json)
  end
Run Code Online (Sandbox Code Playgroud)

然后我从另一个函数调用它并得到以下内容:

456 |     printf "JSON: %s\n" (json);
                              ^^^^^^
Error: This expression has type string t
       but an expression was expected of type string
Run Code Online (Sandbox Code Playgroud)

不太确定出了什么问题。谁能指出我正确的方向吗?

我希望这个函数返回 HTTP 代码和元组中的主体。

oct*_*ron 6

该函数Cohttp_lwt_unix.Body.to_string不返回字符串,而是返回string Lwt.t,换句话说,承诺返回字符串。

\n

由于您还没有字符串,因此无法打印它。你想要做的是当承诺在未来未知的时间点 \xe2\x80\x94 被解析时打印字符串。

\n

这就是为什么Lwt提供不同的方式来绑定承诺的未来结果并计算这个未来结果。

\n

实际上,您可以使用lwt提供let%lwt绑定运算符的 ppx:

\n
let%lwt json = body |> Cohttp_lwt.Body.to_string in\nFormat.printf "%s" json; ...\n
Run Code Online (Sandbox Code Playgroud)\n

绑定>>=运算符

\n
let json_promise = body |> Cohttp_lwt.Body.to_string in\njson_promise >>= (fun json ->\n  ...\n)\n
Run Code Online (Sandbox Code Playgroud)\n

或等效的bind函数:

\n
let json_promise = body |> Cohttp_lwt.Body.to_string in\nLwt.bind json_promise (fun json ->\n  ...\n)\n
Run Code Online (Sandbox Code Playgroud)\n