正如评论中提到的,没有办法在多个文件之间拆分具有循环依赖关系的函数(或类型)。签名文件主要用于文档目的,因此它们无济于事。
如果不知道依赖项到底是什么,就很难给出一些建议。但是,可以使用函数或接口重构实现的某些部分。例如,如果您有:
let rec process1 (a:T1) =
match a with
| Leaf -> 0
| T2Thing(b) -> process2 b
and process2 (b:T2) =
match b with
| T1Thing(a) -> process1 a
您可以修改函数process1
以将第二个函数作为参数。这使得可以在两个文件之间拆分实现,因为它们不再相互递归:
// File1.fs
let process1 (a:T1) process2 =
match a with
| Leaf -> 0
| T2Thing(b) -> process2 b
// File2.fs
let rec process2 (b:T2) =
match b with
| T1Thing(a) -> process1 a process2
如果你能找到一些更清晰的结构——例如两个函数块包含逻辑相关的函数并且需要相互访问,那么你也可以定义一个接口。这对于只有两个函数的示例没有多大意义,但它看起来像这样:
type IProcess2 =
abstract Process : T2 -> int
let process1 (a:T1) (process2:IProcess2) =
match a with
| Leaf -> 0
| T2Thing(b) -> process2.Process b
let rec process2 (b:T2) =
let process2i =
{ new IProcess2 with
member x.Process(a) = process2 a }
match b with
| T1Thing(a) ->
process1 a process2i
无论如何,这些只是一些通用技术。如果不了解您正在使用的类型的更多信息,很难给出更精确的建议。如果您可以分享更多细节,也许我们可以找到一种方法来避免一些递归引用。