与原始类型不兼容的类型类

Incompatible typeclasses with primitive types

我不确定如何表达这个问题以进行有用的 Google 搜索,所以我希望你们能帮助我。我正在使用 OCaml Sqlite3 库。它有一个用户定义的数据类型,看起来像

module Data = struct
  type t =
    | NONE
    | NULL
    | INT of int64
    | FLOAT of float
    | TEXT of string
    | BLOB of string

我正在尝试按照教程进行操作:

http://www.mega-nerd.com/erikd/Blog/CodeHacking/Ocaml/snip_sqlite.html。具体来说,我尝试 运行 函数

let create_tables db =
      (* Create two tables in the database. *)
      let tables =
      [    "people", "pkey INTEGER PRIMARY KEY, first TEXT, last TEXT, age INTEGER" ;
      "cars", "pkey INTEGER PRIMARY KEY, make TEXT, model TEXT" ;
      ]
  in
  let make_table (name, layout) =
      let stmt = Printf.sprintf "CREATE TABLE %s (%s);" name layout in
      match Sqlite3.exec db stmt with
      |    Sqlite3.Rc.OK -> Printf.printf "Table '%s' created.\n" name
      |    x -> raise (E (Sqlite3.Rc.to_string x))
  in
  List.iter make_table tables

我遇到的问题是当我尝试在 utop 中使用文件时我得到

Error: This expression has type string * string but an expression was expected of type Data.t * Data.t. Type string is not compatible with type Data.t

这没有意义,因为字符串应该被强制转换为 Data.t,不是吗?我在这里不明白什么?

谢谢!

编辑:似乎解决这个问题的方法是

Data.TEXT "my text query stuff here"

虽然这看起来很难看。创建这些明确的列表看起来像

let tables =
      [ Data.TEXT "people", Data.TEXT "pkey INTEGER PRIMARY KEY, first TEXT, last TEXT, age INTEGER" ;
      Data.TEXT "cars", Data.TEXT "pkey INTEGER PRIMARY KEY, make TEXT, model TEXT" ;
      ]

有没有更惯用的方法来处理这个问题?

您可以定义自己的从字符串对到 Data.t:

对的转换函数
let todt (a, b) = (Data.TEXT a, Data.TEXT b)

那你可以说

List.map todt tables

(使用表的原始定义作为字符串对的列表。)