I'm stuck with one of the examples from "Real World Functional Progamming", chapter 8 -- decision trees. If I run this code in FSI (version 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
the value tree is
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";}
the values for Positive and Negative for the first two nodes are null, instead of references declared below (aleft, aright, bleft). Hence a function to parse the tree would fail.
How should I define the (recursive) type of a decision tree, in order to obtain a tree structure value?
val tree : Decision = Query {Title = "A";
Positive = aleft;
Negative = aright;}
val aleft : Decision = Query {Title = "B";
Positive = bleft;
Negative = Result "Yes";}
...
If I understand correctly it doesn't look like you need a recursive value here. You should be able to just define the entire tree at once:
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" } }
Printing tree yields this output:
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";};}
This looks very much like a compiler bug.
Here's a shorter repro:
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
Initialization here fails in the same way: a = B (A null).
Filed here, let's see what response I get.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With