I’m very new to OCaml (~2 weeks) and I keep running into issues when adding Base/Core and modules that implement either PPX or deriving.
How are you supposed to mitigate these issues?
Both have taken quite a bit of work to identify the cause, is there a way to more easily understand where the problems are coming from?
Two examples follow:
The first issue is when I pull in Base
with [@@deriving yaml]
open Base
type book = {
title: string;
authors: string list
} [@@deriving yaml]
Compile error:
File "bin/main.ml", line 9, characters 11-22:
9 | authors: string list
^^^^^^^^^^^
Error (warning 6 [labels-omitted]): label f was omitted in the application of this function.
File "bin/main.ml", line 9, characters 11-17:
9 | authors: string list
^^^^^^
Error: This expression should not be a function, the expected type is
'a Base.List.t
The second issue was when I added Core
and pgocaml
's PPX in the same module, trying to compile failed. I reduced the issue to the following, where String.concat "" ["a"]
existed in the pgocaml
PPX.
Starting with:
open Core
open PGOCaml
let () =
let dbh = PGOCaml.connect () in
let insert name salary =
[%pgsql dbh "insert into employees (name, salary) VALUES ($name, $salary)"]
in
ignore(insert "Chris" 1_000.0);
Then run ppxfind
generates the following, and below is a simplified result which conflicts with Core
.
(*
PGHOST=localhost PGUSER=postgres PGDATABASE=postgres PGPASSWORD=example ppxfind -legacy pgocaml_ppx ./bin/main.ml
PGHOST=localhost PGUSER=postgres PGDATABASE=postgres PGPASSWORD=example dune exec bin/main.exe --
*)
open Core
open PGOCaml
let () =
let dbh = PGOCaml.connect () in
let insert name salary =
PGOCaml.bind
(let dbh = dbh in
let params : string option list list =
[[Some (((let open PGOCaml in string_of_string)) name)];
[Some (((let open PGOCaml in string_of_float)) salary)]] in
let split =
[`Text "insert into employees (name, salary) VALUES (";
`Var ("name", false, false);
`Text ", ";
`Var ("salary", false, false);
`Text ")"] in
let i = ref 0 in
let j = ref 0 in
let query =
String.concat ""
(List.map
(function
| `Text text -> text
| `Var (_varname, false, _) ->
let () = incr i in
let () = incr j in "$" ^ (string_of_int j.contents)
| `Var (_varname, true, _) ->
let param = List.nth params i.contents in
let () = incr i in
"(" ^
((String.concat ","
(List.map
(fun _ ->
let () = incr j in
"$" ^ (string_of_int j.contents)) param))
^ ")")) split) in
let params = List.flatten params in
let name = "ppx_pgsql." ^ (Digest.to_hex (Digest.string query)) in
let hash =
try PGOCaml.private_data dbh
with
| Not_found ->
let hash = Hashtbl.create 17 in
(PGOCaml.set_private_data dbh hash; hash) in
let is_prepared = Hashtbl.mem hash name in
PGOCaml.bind
(if not is_prepared
then
PGOCaml.bind (PGOCaml.prepare dbh ~name ~query ())
(fun () -> Hashtbl.add hash name true; PGOCaml.return ())
else PGOCaml.return ())
(fun () -> PGOCaml.execute_rev dbh ~name ~params ()))
(fun _rows -> PGOCaml.return ()) in
ignore (insert "Chris" 1_000.0)
That compiled results in this error.
File "bin/main.ml", lines 44-59, characters 11-38:
44 | ...........(List.map
45 | (function
46 | | `Text text -> text
47 | | `Var (_varname, false, _) ->
48 | let () = incr i in
...
56 | (fun _ ->
57 | let () = incr j in
58 | "$" ^ (string_of_int j.contents)) param))
59 | ^ ")")) split)...
Error: The function applied to this argument has type ?sep:string -> string
This argument cannot be applied without label
Simplified down, String.concat "" ["a"]
with Core
is not compatible.
open Core
let () =
let query = String.concat "" ["a"] in
print_endline query;
Compile Error:
The function applied to this argument has type ?sep:string -> string
This argument cannot be applied without label