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

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

Мне здесь не хватает чего-то очень простого?


person Dmitri Nesteruk    schedule 25.03.2009    source источник


Ответы (4)



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

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

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

person Kurt Schelfthout    schedule 25.03.2009

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

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

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

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

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

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

person Shaun Luttin    schedule 23.02.2018

Функции, объявленные через 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 # технически являются методами интерфейса командной строки, так как это то, для чего они скомпилированы. Как есть, неясно, о чем вопрос, но я предполагаю из принятого ответа, что он не только запрашивает методы, как следует из названия.

person Vandroiy    schedule 07.11.2014
comment
О методах разных типов вы говорите, что это тривиально; он просто работает, но есть тонкость, которую легко упускать из виду: когда вы используете inline и / или определенные ограничения членов, вам может потребоваться объявить их по порядку (т. е. обратные ссылки приведут к странным и трудно диагностируемым ошибкам). См. Отчет об ошибке. Важен порядок элементов типа - person Abel; 22.12.2016