模块之间的F#相互递归 [英] F# mutual recursion between modules
问题描述
对于F#中的递归,在特殊情况下(仅是一个函数自身调用,或者一组物理上彼此相邻的函数相互调用),现有文档清楚地说明了如何执行此操作.
For recursion in F#, existing documentation is clear about how to do it in the special case where it's just one function calling itself, or a group of physically adjacent functions calling each other.
但是在通常情况下,不同模块中的一组函数需要相互调用,您该怎么做?
But in the general case where a group of functions in different modules need to call each other, how do you do it?
推荐答案
我认为F#中没有实现此目的的方法.通常,可以使用不需要这种方式的结构来构建应用程序,因此,如果您描述了您的方案,则可能会得到一些有用的评论.
I don't think there is a way to achieve this in F#. It is usually possible to structure the application in a way that doesn't require this, so perhaps if you described your scenario, you may get some useful comments.
无论如何,有多种方法可以解决此问题-您可以声明一条记录或一个接口来保存需要从模块中导出的功能.接口也允许您导出多态函数,因此它们可能是更好的选择:
Anyway, there are various ways to workaround the issue - you can declare a record or an interface to hold the functions that you need to export from the module. Interfaces allow you to export polymorphic functions too, so they are probably a better choice:
// Before the declaration of modules
type Module1Funcs =
abstract Foo : int -> int
type Module2Funcs =
abstract Bar : int -> int
然后,模块可以导出一个实现接口和函数的值,而该值要求另一个模块可以将其用作参数(或者可以将其存储为可变值).
The modules can then export a value that implements one of the interfaces and functions that require the other module can take it as an argument (or you can store it in a mutable value).
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
也可以使用Reflection自动完成初始化,但这有点丑陋,但是如果您真的经常需要它,我可以想象为此开发一些可重用的库.
The initializationcould be also done automatically using Reflection, but that's a bit ugly, however if you really need it frequently, I could imagine developing some reusable library for this.
在许多情况下,这感觉很难看,重组应用程序以避免递归引用是一种更好的方法(实际上,我发现面向对象编程中的类之间的递归引用常常很混乱).但是,如果您确实需要这样的东西,那么使用接口/记录导出函数可能是唯一的选择.
In many cases, this feels a bit ugly and restructuring the application to avoid recursive references is a better approach (in fact, I find recursive references between classes in object-oriented programming often quite confusing). However, if you really need something like this, then exporting functions using interfaces/records is probably the only option.
这篇关于模块之间的F#相互递归的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!