F#:类型和函数之间是否可以相互递归? [英] F#: is mutual recursion between types and functions possible?
问题描述
我可以使用and
关键字设置相互递归的函数定义.我也可以将and
用于相互递归的类型,但是如果类型和函数之间存在相互递归的关系怎么办?是使函数成为该类型的成员的唯一选择,还是在这里我也可以使用类似于and
的东西?
I can use the and
keyword to set up mutually recursive function definitions. I can also use and
for mutually recursive types, but what if there is a mutually recursive relationship between a type and a function? Is my only option to make the function a member of the type or can I use something similar to and
here too?
添加一个简化的伪示例,希望它能说明我正在尝试做的事情
Adding a simplified pseudo-example that I hope illustrates what I'm trying to do
// A machine instruction type
type Instruction = Add | CallMethod int (* method ID *) | ...
// A class representing a method definition
type MethodDef (fileName : string) =
member x.Params with get () = ...
member x.Body with get() =
let insts = readInstructions fileName
Array.map toAbstractInst insts
// a more abstract view of the instructions
and AbstractInstruction = AbstAdd | AbstCallMethod MethodDef | ...
// a function that can transform an instruction into its abstract form
let toAbstractInst = function
| Add -> AbstAdd
| CallMethod methodId -> AbstCallMethod (somehowResolveId methodId)
| ...
因此您可以在这里看到递归关系是间接建立的:MethodDef<-> AbstractInst AND MethodDef-> toAbstractInst-> AbstractInstruction(其中->表示依赖于")
So you can see here that the recursive relationship is set up pretty indirectly: MethodDef <-> AbstractInst AND MethodDef -> toAbstractInst -> AbstractInstruction (where -> means "depends on")
推荐答案
没有示例就很难回答这个问题
This question is difficult to answer without an example
-
如果您有没有成员的相互递归类型,则这些类型不需要了解函数(因此您可以先定义类型,然后再定义函数).
If you have mutually recursive types that do not have members, then the types don't need to know about the functions (so you can first define types and then functions).
如果您具有互为递归的类型,并且具有功能作为成员,则成员可以相互看到(跨类型),您应该没事
If you have mutually recursive types that have the functions as members, then the members can see each other (across types) and you should be fine
唯一棘手的情况是当您具有相互递归的类型,相互递归的函数并且您还希望将某些函数公开为成员时.然后,您可以使用类型扩展名:
The only tricky case is when you have mutually recursive types, mutually recursive functions and you also want to exposes some functions as members. Then you can use type extensions:
// Declare mutually recursive types 'A' and 'B'
type A(parent:option<B>) =
member x.Parent = parent
and B(parent:option<A>) =
member x.Parent = parent
// Declare mutually recursive functions 'countA' and 'countB'
let rec countA (a:A) =
match a.Parent with None -> 0 | Some b -> (countB b) + 1
and countB (b:B) =
match b.Parent with None -> 0 | Some a -> (countA a) + 1
// Add the two functions as members of the types
type A with
member x.Count = countA x
type B with
member x.Count = countB x
在这种情况下,您可以只使两种类型的countA
和countB
成员,因为这样会更容易,但是如果您要编写更复杂的代码作为函数编写,则可以选择
In this case, you could just make countA
and countB
members of the two types, because it would be easier, but if you have more complex code that you want to write as functions, then this is an option.
如果所有内容都写在一个模块中(在一个文件中),则F#编译器会将类型扩展作为标准实例成员进行编译(因此,从C#的角度来看,它就像普通类型一样).如果在单独的模块中声明扩展,则它们将被编译为F#特定的扩展方法.
If everything is written in a single module (in a single file), then the F# compiler compiles type extensions as standard instance members (so it looks just like normal type from the C# point of view). If you declare extensions in a separate module, then they will be compiled as F#-specific extension methods.
这篇关于F#:类型和函数之间是否可以相互递归?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!