Я всегда полагал, что в 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
ключевое слово вне страницы о рекурсивных функциях, и с 03.01.2010 это не упоминает случай, о котором я спрашиваю.
Точно то же самое происходит с нестатическими участниками.
Так, почему это - синтаксическая ошибка использовать rec
ключевое слово на функциях членства типа записи?
'let rec' заключается не в определении рекурсивных функций, а в определении привязки в окружении, включающей привязку для текущей переменная, подлежащая привязке. Вы можете использовать 'let rec' так же хорошо, как и для определения, например, бесконечного списка. Часто, вы не хотите, чтобы привязка была включена. в окружении, так как вы можете захотеть получить доступ к более ранней переменной с тем же именем.
Когда вы определяете статическую функцию-член, факториал, вы ищете привязку не для переменной "факториал", а для типа MyRecordType" (который находится в окружении как определение типа), и если случается, что у него есть статическая функция-член, называемая "факториал", который у него есть.
] Все функции "члена" неявно "повторяются" в пределах типа, в котором они определены в. [
].