Conversation
|
Checking. |
| /// A balanced binary tree similar to a red-black tree which may have less predictable performance. | ||
| type AaTree<'T when 'T: comparison> = | ||
| | E | ||
| | T of int * AaTree<'T> * 'T * AaTree<'T> |
There was a problem hiding this comment.
Consider using names for the T case data as in the Shape example here - https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/discriminated-unions .
There was a problem hiding this comment.
Good idea. Would be helpful when editing the tree itself to specify the different data types mean. (Added.)
| testList "AaTree" [ | ||
|
|
||
| (* Existence tests. *) | ||
| test "test isEmpty" { |
There was a problem hiding this comment.
Can we divide the tests to have test per assertion/aspect and explain in the test name which aspect of isEmpty we are testing? Here I would go with something along the lines of "test isEmpty returns true for an empty aatree" and "test isEmpty returns false for a single element aatree". This is additional work for you to do now, but it will make future maintenance easier.
|
|
||
| (* Existence tests. *) | ||
| test "test isEmpty" { | ||
| Expect.isTrue <| AaTree.isEmpty AaTree.empty <| "" |
There was a problem hiding this comment.
Let's not use empty assertion messages
|
|
||
| test "test tryFind" { | ||
| let tree = AaTree.ofList ["hello"; "bye"] | ||
| Expect.equal (Some("hello")) <| AaTree.tryFind "hello" tree <| "" |
There was a problem hiding this comment.
Consider using AAA(arrange, act, assert) structure for the test.
Maybe:
let tree = AaTree.ofList ["hello"; "bye"]
let result = AaTree.tryFind "hello" tree
Expect.equal (Some "hello" ) result "tryFind should find hello in aatree created from [hello; bye]"| let array = [|1; 2; 3; 4; 5|] | ||
| let tree = AaTree.ofArray array | ||
| for i in array do | ||
| Expect.isTrue <| AaTree.exists i tree <| "" |
There was a problem hiding this comment.
Expect.containsAll?
| let inputList = [0;1;2;3] | ||
| let tree = AaTree.ofList inputList | ||
| let outputList = AaTree.toList tree | ||
| Expect.equal outputList inputList "" |
There was a problem hiding this comment.
Is it guaranteed that AaTree.toList output will be sorted?
| open FSharpx.Collections | ||
| open System.Collections.Generic | ||
|
|
||
| (* Implementation guided by following paper: https://arxiv.org/pdf/1412.4882.pdf *) |
There was a problem hiding this comment.
I will be able to familiarize myself with it on Tuesday.
|
I think all of these are good suggestions and appreciate your rigorous standards. I'll have them implemented in the next few days hopefully. |
|
|
||
| interface IEnumerable<'T> with | ||
| member x.GetEnumerator() = | ||
| (x.ToList() :> _ seq).GetEnumerator() |
| let toList (tree: AaTree<'T>) = | ||
| foldBack (fun a e -> e::a) [] tree | ||
|
|
||
| let toSeq (tree: AaTree<'T>) = |
There was a problem hiding this comment.
Could we provide a lazy implementation? IMO it is unexpected and surprising for the user that just getting the seq, without even using it is O(n). Maybe something along the lines of:
let rec toSeq (tree: AaTree<'T>) =
seq{
match tree with
| E -> ()
| T(_, l, v, r) ->
yield! toSeq l
yield v
yield! toSeq r
}?
| open FSharpx.Collections | ||
| open FSharpx.Collections.Experimental | ||
| open Expecto | ||
| open Expecto.Flip |
There was a problem hiding this comment.
I believe that you are not using the flip style and that the code will compile again if you remove it.
|
Hi @gdziadkiewicz and thanks again for the feedback. (I personally think it's easier to reply "here" rather than you jumping up/down the page navigating to different comments, but let me know if you prefer the other way of individual threads.)
|
|
I reviewed my code and compared it with the paper (and also with the Isabelle HOL proof linked below which corrects the paper in a couple of places) and made some changes. Summary of my mistakes (now fixed):
Summary of changes from the proof (corrects errors in the paper, and corrections now implemented in code):
Isabelle HOL proof for reference: https://isabelle.in.tum.de/library/HOL/HOL-Data_Structures/AA_Set.html . |
|
@hummy123 the CI build is failing due to problems with code formatting. Could you resolve that? |
| then split <| (skew <| T(h, l, v, insert item r)) | ||
| else node | ||
|
|
||
| (* nlvl function fixed according to Isabelle HOL prrof below: *) |
|
@gdziadkiewicz Got it working thanks to your help (haven't used FAKE/GitHub actions much before). Here's the action running successfully on my own fork: https://github.com/hummy123/FSharpx.Collections/actions/runs/3841007372/jobs/6540731078 . (Also updated FAKE as it was giving me errors.) |
|
@hummy123 I'm sorry that I'm not able to work on it quicker. Would you mind if I add some property tests to your code and change the |
|
@gdziadkiewicz No worries - appreciate your time. Anything that makes the code better and tests more resilient sounds good to me, so go ahead. |

I wasn't able to run the test in this repository as I don't have .NET 6.0.401 SDK installed (only a version matching .NET 7), but I don't expect anything to break since it was just mostly a copy-paste from my other repository.
Appreciate the time taken in reviewing this.