我对如何让两种方法相互呼叫感到有点困惑(即A()
呼叫B()
和B()
呼叫A()
)。似乎F#只在代码中遇到它后“看到”该方法,所以如果它没有,它只是说值或构造函数尚未被定义。
我错过了一些非常基本的东西吗?
答案 0 :(得分:43)
答案 1 :(得分:21)
由于问题是关于方法,而Brian的答案是关于函数的,可能有必要指出你可以对类型使用类似的语法:
type A() =
let b = new B()
member x.MethodA() = b.MethodB()
and B() =
member x.MethodB() = ()
另请注意,默认情况下成员是'let rec'(实际上我认为它们不能递归)。
答案 2 :(得分:5)
F#4.1介绍mutually recursive modules and namespaces。
这些是and
关键字的替代方案。
module rec PingPong = // <------ rec keyword here.
let pong() =
printfn "pong"
ping()
let ping () =
printfn "ping"
pong()
rec
关键字定义了“允许所有包含的代码相互递归的模块和命名空间。”
答案 3 :(得分:4)
let rec a () = b ()
and b () = ()
这些是相互递归的函数。
type T () =
member t.A () = t.B()
member t.B () = ()
这是微不足道的;它只是工作。 请注意Abel的评论。
type TypeA () =
member t.A (b : TypeB) = b.B()
and TypeB () =
member b.B () = ()
这使用相互递归类型的type ... and
语法。
通常情况下,and
仅在双向调用时使用。否则,最好重新排序声明,以便首先调用被调用的函数。对于类型推理和可读性来说,通常有助于避免循环依赖,并且不会将它们暗示在它们未被使用的地方。
我建议将问题编辑为要求一般的功能,或者要求不同的类型(在这种情况下,我会从这个答案中删除前两个案例)。方法通常被认为是函数的子集,这是一般的数学术语。但是,所有F#函数在技术上都是 CLI方法,因为它们是编译到的。因此,目前尚不清楚问题的要求,但我从接受的答案中假设它不仅要求方法,因为标题意味着。