Как сделать так, чтобы два метода вызывали друг друга?

Я немного запутался в том, как заставить два метода вызывать друг друга (т.е. иметь 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, так как это то, для чего они компилируются. Таким образом, не ясно, о чем вопрос, но я предполагаю из принятого ответа, что он не только запрашивает методы, как подразумевает заголовок.

Другие вопросы по тегам