Как сделать так, чтобы два метода вызывали друг друга?
Я немного запутался в том, как заставить два метода вызывать друг друга (т.е. иметь A()
вызов B()
а также B()
вызов A()
). Кажется, что F# только "видит" метод после того, как он встречен в коде, поэтому, если это не так, он просто говорит, что значение или конструктор не были определены.
Я что-то здесь упускаю?
4 ответа
'let rec... and...' - это синтаксис, который вы ищете.
let rec F() =
G()
and G() =
F()
Смотрите также Приключения в F# Co-Recursion.
Поскольку вопрос касается методов, а ответ Брайана о функциях, может быть, полезно указать, что вы можете использовать аналогичный синтаксис для типов:
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
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, так как это то, для чего они компилируются. Таким образом, не ясно, о чем вопрос, но я предполагаю из принятого ответа, что он не только запрашивает методы, как подразумевает заголовок.