Являются ли бесконечные типы (они же Рекурсивные типы) невозможными в F #?
-
22-07-2019 - |
Вопрос
Я болтал с Садек Дроби в твиттере, когда заговорили о том, что F #, похоже, не поддерживает Бесконечные типы.Оказывается, что в C # вы можете сделать что-то в этом роде:
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 }
Меня бы заинтересовало практическое применение.Или даже непрактичный :)