Я пытаюсь сделать циклический граф в F #
Мой тип узла выглядит примерно так:
type Node = { Value : int; Edges : Node list }
Мой вопрос: нужно ли мне сделать Edges изменчивым, чтобы иметь циклы?
Я пытаюсь сделать циклический граф в F #
Мой тип узла выглядит примерно так:
type Node = { Value : int; Edges : Node list }
Мой вопрос: нужно ли мне сделать Edges изменчивым, чтобы иметь циклы?
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>
(поскольку последовательности по умолчанию ленивы), но это будет каждый раз пересчитывать края, поэтому вы, вероятно, не хотите этого делать.