OCaml: Lwt expression was expected of type unit Lwt.t

风格不统一 提交于 2019-12-24 05:55:00

问题


I wanted to write for my OUnit tests a little server that when a client connect on a socket, send data to the client and quit.

Because I wanted to use this in my tests, I thought that I should create a server in a thread and create a client in a thread. So here is the code:

open Sys
open Unix
open Lwt

(* a simple server that send a message when a client  connects
 * compile with
 * ocamlfind ocamlc -o lwt_server -package lwt,lwt.unix,unix  -linkpkg -g lwt_server.ml
 * http://baturin.org/code/lwt-counter-server/
 * https://mirage.io/wiki/tutorial-lwt
 * http://aubedesheros.blogspot.fr/2011/05/ocaml-lwt-mini-tutorial.html
 *)

let host = Unix.inet_addr_loopback (* 127.0.0.1 *)
let port = 6600
let max_pending_request = 10

(* Initialize logging capabilities at INFO level *)

let () = Lwt_log.add_rule "*" Lwt_log.Info

let send_message oc =
  Lwt_io.write_line oc "test"

let accept_connection conn =
  let fd, _ = conn in
  let oc = Lwt_io.of_fd Lwt_io.Output fd in
  Lwt.on_failure (send_message oc ) (fun e -> Lwt_log.ign_error (Printexc.to_string e));
  Lwt_log.info "New connection" >>= return

let create_server sock =
  let serve () =
    Lwt_unix.accept sock >>= accept_connection
  in serve

let sock_recv sock maxlen =
  let str = Bytes.create maxlen in
  let recvlen  = recv sock str 0 maxlen [] in
  String.sub str 0 recvlen

let sock_read sock =
  let answer = sock_recv sock 512 in
    Lwt_io.write_line Lwt_io.stdout answer

let create_socket () =
  let sock = Lwt_unix.socket PF_INET SOCK_STREAM 0 in
  Lwt_unix.bind sock @@ ADDR_INET(host, port);
  Lwt_unix.listen sock max_pending_request;
  sock


let () =
  let sock = create_socket () in
    let threads = Lwt.join [create_server sock; sock_read sock] in
      Lwt_main.run threads

Here is the command I use in oder to compile it and the error message

ocamlfind ocamlc -o lwt_server -package lwt,lwt.unix,unix  -linkpkg -g lwt_server.ml
File "lwt_server.ml", line 53, characters 28-46:
Error: This expression has type unit -> unit Lwt.t
       but an expression was expected of type unit Lwt.t

The line 53 refers to (no joke, I have checked twice):

        let threads = Lwt.join [create_server sock; sock_read sock] in

It is the first time I use Lwt, I am not sure if it is the solution I should use with OUnit.


回答1:


The issue is that create_server sock returns another function of type unit -> unit Lwt.t rather than an Lwt thread (unit Lwt.t) as indicated in the type error:

let create_server sock =
  let serve () =
    Lwt_unix.accept sock >>= accept_connection
  in serve (* serve is a function, not a thread *)

You can rewrite this to return a thread rather than a function to fix your this type error:

let create_server sock =
  Lwt_unix.accept sock >>= accept_connection

I haven't tested the code as a whole, but this should fix the type error.



来源:https://stackoverflow.com/questions/39495672/ocaml-lwt-expression-was-expected-of-type-unit-lwt-t

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!