Как сделать так, чтобы два метода вызывали друг друга? - PullRequest
34 голосов
/ 25 марта 2009

Я немного сбит с толку относительно того, как заставить два метода вызывать друг друга (то есть иметь A() call B() и B() call A()). Кажется, что F # только «видит» метод после того, как он встречен в коде, поэтому, если нет, он просто говорит, что значение или конструктор не был определен .

Я что-то здесь упускаю?

Ответы [ 4 ]

43 голосов
/ 25 марта 2009

'let rec ... and ...' - это синтаксис, который вы ищете.

let rec F() = 
    G()
and G() =
    F()

См. Также Приключения в F # Co-Recursion .

21 голосов
/ 25 марта 2009

Поскольку вопрос касается методов, а ответ Брайана о функциях, может быть, полезно указать, что вы можете использовать аналогичный синтаксис для типов:

type A() =
    let b = new B()
    member x.MethodA() = b.MethodB()
and B() =
    member x.MethodB() = ()

Обратите внимание, что члены по умолчанию являются "let rec" (на самом деле я не думаю, что они могут быть нерекурсивными).

5 голосов
/ 23 февраля 2018

F # 4.1 представляет взаимно рекурсивные модули и пространства имен .

Это альтернатива ключевому слову and.

module rec PingPong = // <------ rec keyword here.

    let pong() = 
        printfn "pong"
        ping() 

    let ping () = 
        printfn "ping"
        pong()

Ключевое слово rec определяет модули и пространства имен, которые "допускают, чтобы весь содержащийся код был взаимно рекурсивным".

4 голосов
/ 07 ноября 2014

Функции, объявленные через 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 для взаимно рекурсивных типов .

Примечания * * 1023 Обычно and используется только в том случае, если вызовы происходят в обоих направлениях. В противном случае, может быть лучше изменить порядок объявлений, чтобы вызываемая функция была первой. Часто для вывода типов и читабельности полезно избегать циклических зависимостей и не подразумевать их там, где они не используются. Я предлагаю отредактировать вопрос либо для запроса функций в целом, либо для запроса разных типов (в этом случае я бы исключил первые два случая из этого ответа). Методы обычно рассматриваются как подмножество функций, которое является общим математическим термином. Однако все функции F # технически CLI-методы , так как это то, для чего они скомпилированы. Таким образом, не ясно, о чем вопрос, но я предполагаю из принятого ответа, что он не только запрашивает методы, как подразумевает заголовок.

...