# HG changeset patch # User Chris Cannam # Date 1639045624 0 # Thu Dec 09 10:27:04 2021 +0000 # Node ID 89310846066cedaa4e0a24e3fc0a23ce8a0af053 # Parent a50862ffc9f0e8bb49d61aa41df9cb8a1862429a For foldli/foldri, avoid using T.foldli/foldri because they have to reconstruct the key; instead do our own counting. Also fix incorrect index passed to f in the slice foldli/foldri functions (they were passing the array index rather than the slice index). diff --git a/persistent-array-slice.sml b/persistent-array-slice.sml --- a/persistent-array-slice.sml +++ b/persistent-array-slice.sml @@ -84,22 +84,24 @@ T.foldlRange f acc (trie, makeRange s) fun foldli f acc (s as S { array = A.A { size, trie }, start, count }) = - T.foldliRange (fn (w, x, acc) => f (Word32.toInt w, x, acc)) - acc (trie, makeRange s) + case T.foldlRange (fn (x, (i, acc)) => (i + 1, f (i, x, acc))) + (0, acc) + (trie, makeRange s) of + (_, acc) => acc fun foldr f acc (s as S { array = A.A { size, trie }, start, count }) = T.foldrRange f acc (trie, makeRange s) fun foldri f acc (s as S { array = A.A { size, trie }, start, count }) = - T.foldriRange (fn (w, x, acc) => f (Word32.toInt w, x, acc)) - acc (trie, makeRange s) - - fun app f (s as S { array = A.A { size, trie }, start, count }) = - T.foldliRange (fn (_, x, _) => f x) - () (trie, makeRange s) - - fun appi f (s as S { array = A.A { size, trie }, start, count }) = - T.foldliRange (fn (w, x, _) => f (Word32.toInt w, x)) - () (trie, makeRange s) + case T.foldrRange (fn (x, (i, acc)) => (i - 1, f (i, x, acc))) + (count - 1, acc) + (trie, makeRange s) of + (_, acc) => acc + + fun app f s = + foldl (fn (x, _) => ignore (f x)) () s + + fun appi f s = + foldli (fn (i, x, _) => ignore (f (i, x))) () s end diff --git a/persistent-array.sml b/persistent-array.sml --- a/persistent-array.sml +++ b/persistent-array.sml @@ -67,13 +67,20 @@ T.foldl f acc trie fun foldli f acc (A { size, trie }) = - T.foldli (fn (w, x, acc) => f (Word32.toInt w, x, acc)) acc trie + (* T.foldli is much slower than T.foldl, because it has to reconstruct + the keys as it goes. It's quicker for us just to count them *) + case T.foldl (fn (x, (i, acc)) => (i + 1, f (i, x, acc))) + (0, acc) trie of + (_, acc) => acc fun foldr f acc (A { size, trie }) = T.foldr f acc trie fun foldri f acc (A { size, trie }) = - T.foldri (fn (w, x, acc) => f (Word32.toInt w, x, acc)) acc trie + (* as foldli *) + case T.foldr (fn (x, (i, acc)) => (i - 1, f (i, x, acc))) + (Word32.toInt size - 1, acc) trie of + (_, acc) => acc fun find f (A { size, trie }) = T.search f trie