Разве бесконечные типы (или рекурсивные типы) невозможны в F #? - PullRequest
12 голосов
/ 04 августа 2009

Я болтал с Садек Дроби в твиттере, когда мне сообщили, что F # не поддерживает бесконечные типы. Оказывается, в C # вы можете сделать что-то вроде этого:

delegate RecDelegate<T> RecDelegate<T>(T x);

Однако после некоторых экспериментов с обеими нашими частями мы определили, что то же самое в F # кажется невозможным как в явном, так и в явном виде.

Явное:

type 'a specialF = 'a->specialF<'a>

ошибка FS0191: определение этого типа включает в себя немедленную циклическую ссылку через аббревиатуру, поле структуры или наследственное отношение.

Неявные:

let rec specialF (x: 'a) = specialF

Несоответствие типов. Ожидая 'б, но учитывая "а ->" б. Полученный тип будет бесконечным при объединении "б" и '' a -> 'b'.

Конечно, это намеренно простые образцы.

Мне было интересно, ошибаюсь ли я. Возможно, я пропустил какой-то тип необходимой аннотации?

Ответы [ 3 ]

7 голосов
/ 04 августа 2009

Вы также можете сделать что-то вроде

type 'a RecType = RecType of ('a -> 'a RecType)

для создания именованного типа, с помощью которого выполняется рекурсия. Теперь это работает:

let rec specialF = RecType (fun _ -> specialF)
6 голосов
/ 04 августа 2009
type d<'T> = delegate of 'T -> d<'T>  //'
let del : d<int> = null
let anotherDel = del.Invoke(1).Invoke(2).Invoke(3)

Я думаю, что вам нужен именованный тип, который может быть представлен непосредственно в CLI для прерывания рекурсии, поэтому в F # это означает, что вам также необходим фактический тип делегата.

3 голосов
/ 07 августа 2009

Рекурсивные типы записей также должны работать.

type A = { A : A }
let rec a : A = { A = a }

Мне было бы интересно практическое применение. Или даже непрактичный:)

...