F#:类型和函数之间是否可以相互递归? [英] F#: is mutual recursion between types and functions possible?

查看:93
本文介绍了F#:类型和函数之间是否可以相互递归?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以使用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

在这种情况下,您可以只使两种类型的countAcountB成员,因为这样会更容易,但是如果您要编写更复杂的代码作为函数编写,则可以选择

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

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