对于如何让两种方法互相调用(即有A()
callB()
和B()
call A()
),我有点困惑。似乎 F# 仅在代码中遇到该方法后才“看到”该方法,因此如果没有,它只会说value 或 constructor has not been defined。
我在这里错过了一些非常基本的东西吗?
对于如何让两种方法互相调用(即有A()
callB()
和B()
call A()
),我有点困惑。似乎 F# 仅在代码中遇到该方法后才“看到”该方法,因此如果没有,它只会说value 或 constructor has not been defined。
我在这里错过了一些非常基本的东西吗?
由于问题是关于方法的,而 Brian 的答案是关于函数的,所以指出您可以对类型使用类似的语法可能很有用:
type A() =
let b = new B()
member x.MethodA() = b.MethodB()
and B() =
member x.MethodB() = ()
另请注意,默认情况下成员是'let rec'(实际上我认为他们不能不递归)。
F# 4.1 引入了相互递归的模块和命名空间。
这些是and
关键字的替代品。
module rec PingPong = // <------ rec keyword here.
let pong() =
printfn "pong"
ping()
let ping () =
printfn "ping"
pong()
该rec
关键字定义了“允许所有包含的代码相互递归”的模块和命名空间。
let rec a () = b ()
and b () = ()
这些是相互递归的函数。
type T () =
member t.A () = t.B()
member t.B () = ()
这是微不足道的;它只是工作。请注意亚伯的评论。
type TypeA () =
member t.A (b : TypeB) = b.B()
and TypeB () =
member b.B () = ()
这使用了相互递归类型type ... and
的语法。
通常,and
仅在呼叫发生在两个方向时使用。否则,最好重新排序声明,以便被调用的函数首先出现。避免循环依赖并在不使用它们的地方不暗示它们通常有助于类型推断和可读性。
我建议编辑这个问题,要么要求一般的功能,要么要求不同的类型(在这种情况下,我会从这个答案中删除前两种情况)。方法通常被认为是函数的子集,这是通用的数学术语。但是,从技术上讲,所有 F# 函数都是CLI 方法,因为它们是编译成的。照原样,目前尚不清楚问题的要求是什么,但我从接受的答案中假设它不仅要求方法,正如标题所暗示的那样。