对于F#中的递归,现有文档清楚地说明了如何在特殊情况下执行它,它只是一个函数调用自身,或者是一组物理上相邻的函数相互调用.
但是在一般情况下,不同模块中的一组功能需要相互调用,你是如何做到的?
我不认为有一种方法可以在F#中实现这一点.通常可以以不需要这种方式构建应用程序,因此,如果您描述了自己的方案,可能会得到一些有用的注释.
无论如何,有多种方法可以解决此问题 - 您可以声明记录或接口来保存从模块导出所需的功能.接口允许您导出多态函数,因此它们可能是更好的选择:
// Before the declaration of modules
type Module1Funcs =
abstract Foo : int -> int
type Module2Funcs =
abstract Bar : int -> int
Run Code Online (Sandbox Code Playgroud)
然后,模块可以导出一个值,该值实现一个接口和函数,这些接口和函数需要另一个模块可以将其作为参数(或者您可以将其存储在可变值中).
module Module1 =
// Import functions from Module2 (needs to be initialized before using!)
let mutable module2 = Unchecked.defaultof<Module2Funcs>
// Sample function that references Module2
let foo a = module2.Bar(a)
// Export functions of the module
let impl =
{ new Module1Funcs with
member x.Foo(a) = foo a }
// Somewhere in the main function
Module1.module2 <- Module2.impl
Module2.module1 <- Module1.impl
Run Code Online (Sandbox Code Playgroud)
初始化也可以使用Reflection自动完成,但这有点难看,但如果你真的经常需要它,我可以想象为此开发一些可重用的库.
在许多情况下,这感觉有点难看,重组应用程序以避免递归引用是一种更好的方法(事实上,我发现面向对象编程中的类之间的递归引用通常相当混乱).但是,如果您真的需要这样的东西,那么使用接口/记录导出函数可能是唯一的选择.