使用Async发出GET请求

时间:2016-01-29 23:14:05

标签: ocaml

取自真实世界OCaml书的chapter 18,我试图打破给出的例子。

我的范围,只是进行GET调用并打印出我们回来的JSON。

这是我的代码(它应该是给定示例的一个子集)

public class rec{
    public static void main (String[] args) {
        int h = 0;
        int numero = Integer.parseInt(args[0]);
        int factor = 0;

        if ( numero == 0 || numero == 1){
            System.out.println(1);
        } else {
            int xpi = factorial(numero-1);
            System.out.println(factor);
        }
    }

    public static int factorial (int n){
        System.out.println("lol");
        if(n==0) {
            return 0;
        } else{ 
            return n* (n-1);
        }
    }
}

我的问题是编译时出现此错误:

(* libraries *)
open Core.Std
open Async.Std


(* Generate a DuckDuckGo search URI from a query string *)
let query_uri query =
  let base_uri = Uri.of_string "http://api.duckduckgo.com/?format=json" in
  Uri.add_query_param base_uri ("q", [query])


(* Extract the "Definition" or "Abstract" field from the DuckDuckGo results *)
let get_definition_from_json json_string =
  match Yojson.Safe.from_string json_string with
  | `Assoc kv_list ->
    let find key =
      begin match List.Assoc.find kv_list key with
      | None | Some (`String "") -> None
      | Some s -> Some (Yojson.Safe.to_string s)
      end
    in
    begin match find "Abstract" with
    | Some _ as x -> x
    | None -> find "Definition"
    end
  | _ -> None


(* Execute the DuckDuckGo search *)
let get_definition word =
  print_endline ("get_definition word:" ^ word);

  Cohttp_async.Client.get (query_uri word)
  >>= fun (_, body) ->
    Pipe.to_list (Cohttp_async.Body.to_pipe body)
  >>| fun strings ->
    (word, get_definition_from_json (String.concat strings))


(* run *)
let () =
  get_definition "OCaml"
  >>= fun (word, def) -> 
    print_endline ("- word: " ^ word);
    (
      match def with
        | None -> print_endline "[EMPTY]"
        | Some str -> print_endline str
    )

如何从延迟中获取字符串,该错误究竟意味着什么? 在本书中,该示例使用奇怪的Command包运行,因此我无法看到如何将其拉出来。

1 个答案:

答案 0 :(得分:1)

run定义中的问题是匿名函数

fun (word, def) -> 
    print_endline ("- word: " ^ word);
    (
      match def with
        | None -> print_endline "[EMPTY]"
        | Some str -> print_endline str
    )

未正确键入以与monadic运算符>>=一起使用。它的类型为string * string -> unit,而>>=此处需要string * string -> unit Deferred.t类型的函数。

如果您在同一章中查看 echo服务器的示例,它将建议采用以下方法:

let run () =
  get_definition "OCaml"
  >>= fun (word, def) -> 
    print_endline ("- word: " ^ word);
    (
      match def with
        | None -> print_endline "[EMPTY]"
        | Some str -> print_endline str
    );
    Deferred.return()

let () =
  ignore(run ());
  never_returns (Scheduler.go ())