Создавать модуль в OCaml динамически

У меня есть несколько модулей, реализующих один и тот же интерфейс. Я хочу загрузить только один из этого модуля в зависимости от одного аргумента, указанного в командной строке.

Я думал использовать модуль первого класса, но проблема в том, что я хочу выполнить некоторые функции до того, как этот модуль будет создан.

На данный момент у меня есть это:

module Arch = (val RetrolixAbstractArch.get_arch() : RetrolixAbstractArch.AbstractArch)


let get_arch () =
  let arch = Options.get_arch() in
  if arch = "" then
    Error.global_error "During analysis of compiler's architecture"
               "No architecture specified"
  else
    if arch = "mips" then
      ( module MipsArch : AbstractArch)
    else
    Error.global_error "During analysis of compiler's architecture"
               (Printf.sprintf "Architecture %s not supported or unknown" arch)      

Но так как командная строка еще не проанализирована, Options.get_arch дай мне пустую строку.

Я хотел бы реализовать синтаксический анализ командной строки до того, как эта функция будет выполнена (без добавления синтаксического анализа в функцию). Является ли это возможным? Должен ли я найти другой способ добиться этого?

1 ответ

Это возможно, но вы должны использовать локальные модули. Это небольшая проблема, которая требует лишь небольшого количества рефакторинга.

let arch_of_name = function
  | "mips" -> (module MipsArch : AbstractArch)
  | "arm"  -> (module Arm)
  | _ -> invalid_arg "unknown arch"


let main () = 
  ...
  let arch_name = get_arch () in
  let module Arch = (val arch_of_name arch_name) in
  (* here you can use module Arch as usual *)

Другой подход состоит в том, чтобы функторизовать ваши модули с арочной структурой и создать ваши функторы, как только вы узнаете архитектуру. Вы можете увидеть полноценный пример здесь (см. Функцию target_of_arch это создает первоклассный модуль для конкретной архитектуры).

Если твой AbstractArch Интерфейс не содержит определения типов, тогда вы можете использовать другие абстракции вместо модулей: записи функций или объектов. Они могут работать более плавно и даже могут позволить вам динамически перегрузить экземпляр arch (сделав arch пример, чтобы быть ссылкой, хотя я бы не предложил это, так как это довольно нечисто, IMO).

Другие вопросы по тегам