F#模块之间的相互递归

rwa*_*ace 2 recursion f#

对于F#中的递归,现有文档清楚地说明了如何在特殊情况下执行它,它只是一个函数调用自身,或者是一组物理上相邻的函数相互调用.

但是在一般情况下,不同模块中的一组功能需要相互调用,你是如何做到的?

Tom*_*cek 7

我不认为有一种方法可以在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自动完成,但这有点难看,但如果你真的经常需要它,我可以想象为此开发一些可重用的库.

在许多情况下,这感觉有点难看,重组应用程序以避免递归引用是一种更好的方法(事实上,我发现面向对象编程中的类之间的递归引用通常相当混乱).但是,如果您真的需要这样的东西,那么使用接口/记录导出函数可能是唯一的选择.