Подтвердить что ты не робот

Рекурсивные функции-члены рекурсивного типа и ключевое слово "rec"

Я всегда считал, что в F # нам нужно использовать ключевое слово rec для каждой рекурсивной функции, например:

let rec factorial = function
| 0 -> 1
| k when k > 0 ->  k * (factorial (k - 1))
| failwith "oops!"

Сегодня я играл с F #, и я придумал код, похожий на следующий:

let MyRecordType =
    { Something     : float;
      SomethingElse : int }
    with
        static member factorial = function
            | 0 -> 1
            | k when k > 0 ->  k * (MyRecordType.factorial (k - 1))
            | failwith "oops!"

Как вы видите, я только что определил рекурсивную функцию, но я сделал то, что сначала казалось ошибкой: я забыл объявить функцию как рекурсивную с помощью ключевого слова rec.

Но, к моему удивлению, компилирует! И еще к этому: если вы добавите ключевое слово rec, то это синтаксическая ошибка!

type MyRecordType =
    { (* ... *) }
    with
        // syntax error:
        static member rec factorial = function
        (* ... *)

Я искал объяснения, но ничего не получил. В документации MSDN я не мог найти никакого упоминания ключевому слову rec вне страницы о рекурсивных функциях и по состоянию на 2010-01 -03 он не упоминает случай, о котором я прошу.

То же самое происходит с нестационарными членами.

Итак, почему это синтаксическая ошибка для использования ключевого слова rec для функций-членов типа записи?

4b9b3361

Ответ 1

'let rec' - это не определение рекурсивных функций, а определение привязки в среде, включающее привязку для текущего переменная, подлежащая привязке. Вы также можете использовать "let rec", чтобы определить, например. бесконечный список. Часто вы не хотите, чтобы привязка была включена в среде, так как вам может потребоваться доступ к более ранней переменной с тем же именем.

Когда вы определяете статическую функцию-член, факториал, вы не ищете привязки для переменной "factorial", а для типа "MyRecordType" (который находится в среде как определение типа), и если он имеет статическую функцию-член, называемую "factorial", который он имеет.

Ответ 2

Все "членные" функции неявно "rec" в пределах того типа, в котором они определены.