OCaml 中的循环依赖控制

问题描述 投票:0回答:1

我的问题如下:

模块 A 称为 Map.ml

let lst = ref [Instance1_ModuleB; Instance2_ModuleB; ...];;
let is_coliding p = DoSomeWork_And_Return_A_Bool ;;
.... other things here.

模块 B 称为 Player.ml

Open Map
class player_object (x_in, y_in, name_in)=

object (self)

method jump () =
       if Map.is_colliding self then
             DoSomeThing ();;
....

任何如何使其发挥作用的线索。

顺便问一下,其他编程语言是如何解决这个问题的?我从不关心 C# 中的这种依赖

dependency-injection module ocaml circular-dependency
1个回答
3
投票

如果你的模块A只需要模块B的类型而不需要任何值,那么你可以使用模块B的接口创建一个moduleB.mli,并在模块A之前编译它:

模块A.ml:

let foo (bar : ModuleB.bar) = bar.baaz

模块B.mli:

class bar : object
  method baaz : int
  method buz : int
end

模块B.ml

class bar =
object(s)
  method baaz = 3
  method buz = ModuleA.foo s
end

但是,如果您对值或函数有循环依赖,则没有简单的解决方案,例如:

模块A.ml:

let li = [new bar; new bar]

let foo (bar : ModuleB.bar) = bar.baaz

一般可以尝试通过使用引用或可变值来打破这种循环依赖:

模块A.ml:

let li = [new bar; new bar]

let foo (bar : ModuleB.bar) = bar.baaz
let _ = ModuleB.initB foo

模块B.ml

let foo = ref (fun x -> (failwith "not initialized" : int))

class bar =
object(s)
  method baaz = 3
  method buz = !foo s
end

let initB f = foo := f
© www.soinside.com 2019 - 2025. All rights reserved.