管理OCaml中的动态依赖项

eve*_*riq 3 ocaml opam

想象一下OCaml中的一个库,它可能需要将数据存储在某个地方.这个持久层可以用不同的库(sqlite,MySQL,PostgreSQL等)实现.并且根据存储的具体技术,它可能提供不同的功能和性能保证.

有哪些方法可以管理此类库的外部依赖项?假设我是用MySQL开发的,我不想在sqlite上引入编译时和运行时依赖.

在C++中,我可能会使用抽象接口,并将具体逻辑放入有条件地包含在我的项目中的模块中(取决于配置开关).我很好奇,任何人都会在OCaml中接近同样的任务.

Tho*_*ard 5

您可能会定义一个模块类型来抽象所有实现.例如

module type DB =
  sig
    type t
    type results

    val execute : t -> string -> results
    ...
  end
Run Code Online (Sandbox Code Playgroud)

然后,您将编写代码以将此模块类型的实现作为参数:

 module MyProg (D : DB) = struct
   let run db =
     let r = D.execute db "SELECT ..." in
     ...
 end
Run Code Online (Sandbox Code Playgroud)

对于图书馆来说,这就是你所需要的.对于可执行程序,您需要一个单独的main函数来连接到某个实际的数据库,这可能是特定于数据库的,但其余的代码只使用了抽象DB.

(当然,你使用的API比这个基于字符串的API更好.这只是一个简单的例子.)

  • 如果您知道在同一个程序中永远不会同时使用两个后端,那么您还可以定义由不同后端实现的公共接口,并在编译时链接正确的接口.优点是您不需要通过DB参数对整个代码库进行操作. (3认同)