From 83bb852ae2992a97734ee73ee8fe3ca129cc1f20 Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Sat, 17 Jan 2026 23:45:20 +0000 Subject: [PATCH] add another test for 'PersistentVector.delete --- fcore/persistent-vector.sml | 35 +++++++++++-- test/persistent-vector-tests.sml | 86 +++++++++++++++++++++----------- 2 files changed, 87 insertions(+), 34 deletions(-) diff --git a/fcore/persistent-vector.sml b/fcore/persistent-vector.sml index 83cf069..cde2a9d 100644 --- a/fcore/persistent-vector.sml +++ b/fcore/persistent-vector.sml @@ -547,18 +547,45 @@ struct fun merge (left, right) = raise Fail "unimplemennted" - fun delete (start, finish, tree) = + fun delete (start, length, tree) = let + val finish = start + length + val matchBeforeStart = prevMatch (start, tree, 1) val matchAfterFinish = nextMatch (finish, tree, 1) - val left = splitLeft (start, tree) in - if matchAfterFinish = ~1 then + if matchBeforeStart = ~1 andalso matchAfterFinish = ~1 then + empty + else if matchAfterFinish = ~1 then (* there is no match after 'finish', so just split left. * No need to decrement or split right, * because the right vector would be empty. *) - left + splitLeft (start, tree) + else if matchBeforeStart = ~1 then + (* We don't want to use left split + * because there are no elements + * before the deletion range's 'start'. + * So we make a right split and then decrement it. *) + let + val right = splitRight (finish, tree) + in + if isEmpty right then + empty + else + let + val startIdx = getStartIdx right + val difference = matchAfterFinish - startIdx + in + if difference = 0 then + right + else if isEmpty right then + empty + else + decrementBy (difference, right) + end + end else let + val left = splitLeft (start, tree) val right = splitRight (finish, tree) in if isEmpty right then diff --git a/test/persistent-vector-tests.sml b/test/persistent-vector-tests.sml index a3d05ad..17114d5 100644 --- a/test/persistent-vector-tests.sml +++ b/test/persistent-vector-tests.sml @@ -285,38 +285,64 @@ struct ] val deleteTests = describe "PersistentVector.delete" - [test - "returns the left side of the vector \ - \when 'finish' is greater than any element in the vector" - (fn _ => - let - (* arrange *) - val inputList = - [ {start = 1, finish = 1} - , {start = 2, finish = 2} - , {start = 3, finish = 3} - , {start = 4, finish = 4} - , {start = 5, finish = 5} - , {start = 6, finish = 6} - , {start = 7, finish = 7} - , {start = 8, finish = 8} - ] - val pv = PersistentVector.fromList inputList + [ test "returns empty vector when deletion range includes every element" + (fn _ => + let + (* arrange *) + val inputList = + [ {start = 1, finish = 1} + , {start = 2, finish = 2} + , {start = 3, finish = 3} + , {start = 4, finish = 4} + , {start = 5, finish = 5} + , {start = 6, finish = 6} + , {start = 7, finish = 7} + , {start = 8, finish = 8} + ] + val pv = PersistentVector.fromList inputList - (* act *) - val pv = PersistentVector.delete (5, 9, pv) + (* act *) + val pv = PersistentVector.delete (0, 11, pv) - (* assert *) - val outputList = PersistentVector.toList pv - val expectedOutput = - [ {start = 1, finish = 1} - , {start = 2, finish = 2} - , {start = 3, finish = 3} - , {start = 4, finish = 4} - ] - in - Expect.isTrue (outputList = expectedOutput) - end)] + (* assert *) + val outputList = PersistentVector.toList pv + val expectedOutput = [] + in + Expect.isTrue (outputList = expectedOutput) + end) + , test + "returns the left side of the vector \ + \when 'length' is greater than any element in the vector" + (fn _ => + let + (* arrange *) + val inputList = + [ {start = 1, finish = 1} + , {start = 2, finish = 2} + , {start = 3, finish = 3} + , {start = 4, finish = 4} + , {start = 5, finish = 5} + , {start = 6, finish = 6} + , {start = 7, finish = 7} + , {start = 8, finish = 8} + ] + val pv = PersistentVector.fromList inputList + + (* act *) + val pv = PersistentVector.delete (5, 4, pv) + + (* assert *) + val outputList = PersistentVector.toList pv + val expectedOutput = + [ {start = 1, finish = 1} + , {start = 2, finish = 2} + , {start = 3, finish = 3} + , {start = 4, finish = 4} + ] + in + Expect.isTrue (outputList = expectedOutput) + end) + ] val tests = [appendTests, toListTests, splitLeftTests, deleteTests] end