模块之间的F#相互递归 [英] F# mutual recursion between modules

查看:60
本文介绍了模块之间的F#相互递归的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆