在OCaml中传递配置环境

在OCaml中传递配置环境,ocaml,Ocaml,我试图理解和/或找到健壮的OCaml应用程序如何处理配置环境的示例。我来自Haskell的世界,在那里我会使用阅读器monad来解决这个问题。特别是,我想定义一个顶级配置,我可以在整个应用程序中传递该配置,但只有应用程序中的一些函数需要使用该配置 为了激励这一点,考虑一个简单的可执行文件,它可以查询数据库。我想定义一个顶级主文件,它可以做一些事情,比如设置一个连接池,或者创建一个在整个应用程序中共享的记录器 我假设OCaml有一些处理这个问题的模式,但我找不到任何好的例子。我不希望定义自己的阅读

我试图理解和/或找到健壮的OCaml应用程序如何处理配置环境的示例。我来自Haskell的世界,在那里我会使用
阅读器
monad来解决这个问题。特别是,我想定义一个顶级配置,我可以在整个应用程序中传递该配置,但只有应用程序中的一些函数需要使用该配置

为了激励这一点,考虑一个简单的可执行文件,它可以查询数据库。我想定义一个顶级主文件,它可以做一些事情,比如设置一个连接池,或者创建一个在整个应用程序中共享的记录器

我假设OCaml有一些处理这个问题的模式,但我找不到任何好的例子。我不希望定义自己的
阅读器
monad,如果不需要的话,我也不希望对整个应用程序进行功能化

尽管如此,这也是丑陋的

main.mli

module Config : sig
    type t = {
        fooConfig : Foo.Config.t;
        dbClientConfig : DB_client.Config.t;
    }
    val make : Foo.Config.t -> DB_client.Config.t -> t
end

val main : Config.t -> unit
我不想让函数“在执行堆栈中处于较高位置”的显式参数显式依赖于它们永远不会使用的配置

是否有一个很好的函数模式来处理这种嵌套依赖性耦合?如果有人能指出任何代码示例,我将不胜感激,这样我就可以研究更好的方法

foo.mli

module Config : sig
    type t = {
        dbConfig : DB_client.Config.t;
    }
end

(** fooFunc will need to pass the dbConfig, but it does not actually explicitly need anything in the config **)
val fooFunc : Config.t -> string -> unit 
db_client.mli

module Config : sig
    type t = {
        connPool : SomeConnPool
    }
end

(** Finally, I need to use the config to grab a connection out of the pool **)
val writeToDb : Config.t -> string -> (string, string) Lwt.result