Ответ 1
Вы также можете сделать что-то вроде
type 'a RecType = RecType of ('a -> 'a RecType)
чтобы создать именованный тип, с помощью которого можно выполнить рекурсию. Теперь это работает:
let rec specialF = RecType (fun _ -> specialF)
я болтал с Садек Drobi на твиттере, когда воспитываться, что F # не кажется, поддерживают Бесконечные типы. Оказывается, что в С# вы можете сделать что-то в этом направлении:
delegate RecDelegate<T> RecDelegate<T>(T x);
Однако после некоторых экспериментов на обеих наших частях мы определили, что одно и то же в F # кажется невозможным как неявным, так и явно.
Явное:
type 'a specialF = 'a->specialF<'a>
ошибка FS0191: определение этого типа включает немедленную циклическую ссылку через аббревиатуру, поле структуры или отношения наследования.
Неявное:
let rec specialF (x: 'a) = specialF
Несоответствие типов. Ожидание "b", но с учетом "a → " b. Полученный тип было бы бесконечно при объединении '' b ' и '' a → 'b'.
Конечно, это преднамеренно простые образцы.
Мне было интересно, если я ошибаюсь. Возможно, я пропустил какую-то необходимую аннотацию?
Вы также можете сделать что-то вроде
type 'a RecType = RecType of ('a -> 'a RecType)
чтобы создать именованный тип, с помощью которого можно выполнить рекурсию. Теперь это работает:
let rec specialF = RecType (fun _ -> specialF)
type d<'T> = delegate of 'T -> d<'T> //'
let del : d<int> = null
let anotherDel = del.Invoke(1).Invoke(2).Invoke(3)
Мне кажется, вам нужен именованный тип, который можно представить непосредственно в CLI, чтобы разбить рекурсию, поэтому в F # это означает, что вам нужен и фактический тип делегата.
Рекурсивные типы записей также должны работать.
type A = { A : A }
let rec a : A = { A = a }
Мне было бы интересно практическое приложение. Или даже непрактичный:)