此表达式具有单位类型,但表达式应为“a Client.io”类型

问题描述 投票:0回答:1

我正在尝试在下面的 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

如果有人能让我知道我还做错了什么,我将不胜感激。

ocaml
1个回答
0
投票

我怀疑这是由于

>>=
造成的,其 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
© www.soinside.com 2019 - 2024. All rights reserved.