Pass the value from one function to another

Hi, I am trying to write a client using cohttp that will fetch a value from the server and write it to irmin database. But I am not able to figure out how to pass the value from the first function that fetches the value to the second function that writes the value to the database.

function body : creates a request to a server
function write : writes the response from function body to irmin
value is the value that needs to passed.

open Lwt.Infix
open Lwt
open Cohttp
open Cohttp_lwt_unix

(* Irmin store with string contents *)
module Store = Irmin_unix.Git.FS.KV(Irmin.Contents.String)

(* Database configuration *)
let config = Irmin_git.config ~bare:true "/tmp/irmin/test"

(* Commit author *)
let author = "Example <example@example.com>"

(* Commit information *)
let info fmt = Irmin_unix.info ~author fmt


let  body =
  Client.get (Uri.of_string "http://localhost:7070/root") >>= fun (resp, body) ->
  let code = resp |> Response.status |> Code.code_of_status in
  Printf.printf "Response code: %d\n" code;
  Printf.printf "Headers: %s\n" (resp |> Response.headers |> Header.to_string);
  body |> Cohttp_lwt.Body.to_string >|= fun body ->
  Printf.printf "Body of length: %d\n" (String.length body);
  body
 

 let value = Lwt_main.run body;
print_endline ("Received body\n" ^ value)



let write  =
  (* Open the repo *)
  Store.Repo.v config >>=

  (* Load the master branch *)
  Store.master >>= fun t ->

  (* Set key "foo/bar" to "testing 123" *)
  Store.set_exn t ~info:(info "Updating foo/bar") ["foo"; "bar"] value >>= fun () ->

  (* Get key "foo/bar" and print it to stdout *)
  Store.get t ["foo"; "bar"] >|= fun x ->
  Printf.printf "foo/bar => '%s'\n" x  ;

  let () = Lwt_main.run write

Hi @sahana123 !
On your theoretical question, passing a value to a function f is done as such:

(* gobal value *)
let value = (* some value, maybe given back by a function *)
...
let another_value = f value (* with eventually other arguments *)

(* or with a local value *)
let value = (* some value *)
in
let another_value = f value

But I think this is not really your problem there. What is your problem with this code: Does it compile ? If not what is your error message ? If yes what does it do and what would you expect instead ?

To me the part of your code there:

let value = Lwt_main.run body;
print_endline ("Received body\n" ^ value)

is wrong (I think your compiler should state you “Unbound value value”) and should be written as such:

let value = Lwt_main.run body
let () = print_endline ("Received body\n" ^ value)
(*
you could write also, if you wanted:
let value = Lwt_main.run body;;
let () = print_endline ("Received body\n" ^ value)
*)

Improper use of “;” leads to so much errors. In brief never use it to state “I am done with the block of computation I was writing”. Use “;;” if really you want, but if your program is syntactically correct the compiler do not need anything.

On the "let () = ", it may be not necessary, but I am not sure (and it will work with it for sure). If you want to perform a computation which is only a side-effect, I would prefer this way of writing.

If you are new to ocaml, I suggest you find resources to dig into the language (there are really good books available online), because it will prevent you from using libraries.

I hope I somewhat understood what you needed, please tell me if I misunderstood.
Best !

Hi ,
yes I am getting syntax error.

File “store.ml”, line 99, characters 29-29:
Error: Syntax error

Line no 99 is : let () = Lwt_main.run write

P.S.: I removed the semi-colon from the line let value = Lwt_main.run body;

It is because of the preceding semicolon at the end of line:

  Printf.printf "foo/bar => '%s'\n" x  ;

I strongly advise you how ocaml syntax and semantic work, find an online course or a book. I think you will be very limited in your ability to use the language, if you do not. (and beware of semicolons :wink: )
Have a good day !

Hi,
Yes I am new to Ocaml. I have gone through the documentation to learn the basics. Now I need to practice the same :slight_smile: ( easier to remember)

I have restructured the code.

open Lwt.Infix
open Lwt
open Cohttp
open Cohttp_lwt_unix

(* Irmin store with string contents *)
module Store = Irmin_unix.Git.FS.KV(Irmin.Contents.String)

(* Database configuration *)
let config = Irmin_git.config ~bare:true "/tmp/irmin/test"

(* Commit author *)
let author = "Example <example@example.com>"

(* Commit information *)
let info fmt = Irmin_unix.info ~author fmt




let  body =
  Client.get (Uri.of_string "http://localhost:7070/root") >>= fun (resp, body) ->
  let code = resp |> Response.status |> Code.code_of_status in
  Printf.printf "Response code: %d\n" code;
  Printf.printf "Headers: %s\n" (resp |> Response.headers |> Header.to_string);
  body |> Cohttp_lwt.Body.to_string >|= fun body ->
  Printf.printf "Body of length: %d\n" (String.length body);
  body

 
 let value2 = Lwt_main.run body

 let write =
  (* Open the repo *)
  Store.Repo.v config >>=

  (* Load the master branch *)
  Store.master >>= fun t ->

  (* Set key "foo/bar" to "testing 123" *)
  Store.set_exn t ~info:(info "Updating foo/bar") ["foo"; "bar"] value2 >>= fun () ->

  (* Get key "foo/bar" and print it to stdout *)
  Store.get t ["foo"; "bar"] >|= fun x ->
  Printf.printf "foo/bar => '%s'\n" x  ;;
  
 let aaa = Lwt_main.run  write
 print_endline(aaa)

Error:
File “store.ml”, line 98, characters 25-30:
98 | let aaa = Lwt_main.run write
^^^^^
Error: This expression has type unit t but an expression was expected of type
('a -> 'b -> 'c) t
Type unit is not compatible with type 'a -> 'b -> 'c

You’re missing semicolons here again. The line you posted is interpreted by OCaml as:

let aaa = Lwt_main.run write print_endline aaa

So the expected type of write is a thread consuming two arguments print_endline and aaa. Adding ;; to split the lines will fix that particular error, but there is another: the write thread isn’t returning a string, so you won’t be able to print it. It returns unit: the return value of Printf.printf.

Consider using OCamlformat in your editor: this will format the code in a way that makes its behaviour more clear (e.g. it would have formatted the let aaa line as I did).

Thanks @CraigFe :slight_smile:

1 Like