Дерево решений (рекурсивный тип) - PullRequest
0 голосов
/ 01 мая 2018

Я застрял с одним из примеров из "Функционального программирования реального мира", глава 8 - деревья решений. Если я запускаю этот код в FSI (версия 4.1)

type QueryInfo = {
  Title: string
  Positive: Decision
  Negative: Decision
}
and Decision =
  | Result of string
  | Query of QueryInfo

let rec tree = 
    Query({ Title = "A"
            Positive = aleft; Negative = aright })
and aleft = 
    Query({ Title = "B"
            Positive = bleft; Negative = Result("Yes") })
and aright =
    Query({ Title = "C"
            Positive = Result("No"); Negative = Result("Yes") })
and bleft =
    Query({ Title = "D"
            Positive = Result("No"); Negative = Result("Yes") })

printfn "%A" tree

значение tree равно

val tree : Decision = Query {Title = "A";
                            Positive = null;
                            Negative = null;}
val aleft : Decision = Query {Title = "B";
                              Positive = null;
                              Negative = Result "Yes";}
val aright : Decision = Query {Title = "C";
                              Positive = Result "No";
                              Negative = Result "Yes";}
val bleft : Decision = Query {Title = "D";
                              Positive = Result "No";
                              Negative = Result "Yes";}

значения для Positive и Negative для первых двух узлов: null вместо ссылок, объявленных ниже (aleft, aright, bleft). Следовательно, функция для анализа дерева потерпит неудачу.

Как определить (рекурсивный) тип дерева решений, чтобы получить значение древовидной структуры?

val tree : Decision = Query {Title = "A";
                            Positive = aleft;
                            Negative = aright;}
val aleft : Decision = Query {Title = "B";
                              Positive = bleft;
                              Negative = Result "Yes";}
...

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Это очень похоже на ошибку компилятора.

Вот короткое повторение:

type A = A of B
and B = B of A | C

let rec a = B (A b)
and b = B (A c)
and c = C

Инициализация здесь завершается таким же образом: a = B (A null).

Подано здесь , посмотрим, какой ответ я получу.

0 голосов
/ 02 мая 2018

Если я правильно понимаю, это не похоже на то, что вам нужно рекурсивное значение здесь. Вы должны иметь возможность просто определить все дерево сразу:

let tree = 
  Query { Title = "A"
          Positive = Query { Title = "B"
                             Positive = Query { Title = "D"
                                                Positive = Result("No")
                                                Negative = Result("Yes") }
                             Negative = Result "Yes" }
          Negative = Query { Title = "C"
                             Positive = Result "No"
                             Negative = Result "Yes" } }

Печать tree дает этот вывод:

Query {Title = "A";
       Positive = Query {Title = "B";
                         Positive = Query {Title = "D";
                                           Positive = Result "No";
                                           Negative = Result "Yes";};
                         Negative = Result "Yes";};
       Negative = Query {Title = "C";
                         Positive = Result "No";
                         Negative = Result "Yes";};}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...