Создание циклических графов в F#. Требуется ли изменчивость?

Я пытаюсь сделать циклический граф в F #

Мой тип узла выглядит примерно так:

type Node = { Value : int; Edges : Node list }

Мой вопрос: нужно ли мне сделать Edges изменчивым, чтобы иметь циклы?


person Lay González    schedule 14.12.2014    source источник


Ответы (1)


F# позволяет создавать немедленные рекурсивные ссылки на объекты с помощью циклов, но на самом деле это работает только с (достаточно простыми) записями. Итак, если вы попробуете это в своем определении, это не сработает:

let rec loop = 
  { Value = 0;
    Edges = [loop] }

Тем не менее, вы все равно можете избежать мутации — одной из разумных альтернатив является использование ленивых значений:

type Node = { Value : int; Edges : Lazy<Node list>}

Таким образом, вы даете компилятору «достаточно времени» для создания значения loop, прежде чем ему потребуется оценить ребра (и снова получить доступ к значению loop):

let rec loop = 
  { Value = 0;
    Edges = lazy [loop] }

На практике вы, вероятно, захотите вызвать некоторые функции для создания ребер, но это тоже должно сработать. Вы должны быть в состоянии написать, например. Edges = lazy (someFancyFunction loop).

В качестве альтернативы вы также можете использовать seq<Edges> (поскольку последовательности по умолчанию ленивы), но это будет каждый раз пересчитывать края, поэтому вы, вероятно, не хотите этого делать.

person Tomas Petricek    schedule 14.12.2014