2016-01-29 124 views
3

取自真實世界OCaml書籍的chapter 18,我試圖分解給出的示例。使用異步進行GET請求

我的範圍,只是進行GET調用和打印JSON的東西,我們回來了。

這是我的代碼(這應該是給出的例子的一個子集)

(* 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 
    ) 

我的問題是,我編譯時出現此錯誤:

ocaml setup.ml -build 
Finished, 0 targets (0 cached) in 00:00:00. 
+ /Users/antouank/.opam/system/bin/ocamlfind ocamlc -c -g -annot -bin-annot -thread -package yojson -package threads -package textwrap -package re2 -package core -package cohttp.async -I src -o src/main.cmo src/main.ml 
File "src/main.ml", line 48, characters 18-41: 
Error: This expression has type unit but an expression was expected of type 
    'a Async.Std.Deferred.t = 'a Async_kernel.Deferred0.t 
Command exited with code 2. 
Compilation unsuccessful after building 2 targets (0 cached) in 00:00:00. 
E: Failure("Command ''/usr/local/bin/ocamlbuild' src/main.native -use-ocamlfind -tag debug' terminated with error code 10") 
make: *** [build] Error 1 

我如何獲得字符串超出了延遲,這個錯誤究竟意味着什麼? 在這本書中,這個例子是用一個奇怪的命令包運行的,所以我看不出如何將它拉出來。

回答

1

在你的run定義的問題是,匿名函數

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

不正確輸入到一個一元操作>>=使用。它具有類型string * string -> unit,而>>=在這裏會預期類型string * string -> unit Deferred.t的功能。

如果在同樣的章節看一個回聲服務器的例子,它會提示以下方法:

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()) 
+0

謝謝。我懷疑我必須a)運行「調度程序」,無論如何,b)我必須「忽略迴歸」,但我不知道如何去做。 當我運行你給的代碼片段時,這個例子工作正常,但它不會退出。如何告訴它在完成後退出?我在哪裏可以找到關於'ignore'和'never_returns'的更多信息? – AntouanK