Являются ли бесконечные типы (они же Рекурсивные типы) невозможными в F #?

StackOverflow https://stackoverflow.com/questions/1228644

  •  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 }

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top