Dict.update alter fn is passed a Result

This commit is contained in:
Stuart Hinson 2024-09-19 20:46:44 -04:00
parent 9678046d91
commit 9745e1931c
3 changed files with 597 additions and 597 deletions

View File

@ -509,33 +509,33 @@ removeHelper = \buckets, bucketIndex, distAndFingerprint, data, key ->
## is missing. This is more efficient than doing both a `Dict.get` and then a ## is missing. This is more efficient than doing both a `Dict.get` and then a
## `Dict.insert` call, and supports being piped. ## `Dict.insert` call, and supports being piped.
## ```roc ## ```roc
## alterValue : [Present Bool, Missing] -> [Present Bool, Missing] ## alterValue : Result Bool [Missing] -> Result Bool [Missing]
## alterValue = \possibleValue -> ## alterValue = \possibleValue ->
## when possibleValue is ## when possibleValue is
## Missing -> Present Bool.false ## Err -> Ok Bool.false
## Present value -> if value then Missing else Present Bool.true ## Ok value -> if value then Err Missing else Ok Bool.true
## ##
## expect Dict.update (Dict.empty {}) "a" alterValue == Dict.single "a" Bool.false ## expect Dict.update (Dict.empty {}) "a" alterValue == Dict.single "a" Bool.false
## expect Dict.update (Dict.single "a" Bool.false) "a" alterValue == Dict.single "a" Bool.true ## expect Dict.update (Dict.single "a" Bool.false) "a" alterValue == Dict.single "a" Bool.true
## expect Dict.update (Dict.single "a" Bool.true) "a" alterValue == Dict.empty {} ## expect Dict.update (Dict.single "a" Bool.true) "a" alterValue == Dict.empty {}
## ``` ## ```
update : Dict k v, k, ([Present v, Missing] -> [Present v, Missing]) -> Dict k v update : Dict k v, k, (Result v [Missing] -> Result v [Missing]) -> Dict k v
update = \@Dict { buckets, data, maxBucketCapacity, maxLoadFactor, shifts }, key, alter -> update = \@Dict { buckets, data, maxBucketCapacity, maxLoadFactor, shifts }, key, alter ->
{ bucketIndex, result } = find (@Dict { buckets, data, maxBucketCapacity, maxLoadFactor, shifts }) key { bucketIndex, result } = find (@Dict { buckets, data, maxBucketCapacity, maxLoadFactor, shifts }) key
when result is when result is
Ok value -> Ok value ->
when alter (Present value) is when alter (Ok value) is
Present newValue -> Ok newValue ->
bucket = listGetUnsafe buckets bucketIndex bucket = listGetUnsafe buckets bucketIndex
newData = List.set data (Num.toU64 bucket.dataIndex) (key, newValue) newData = List.set data (Num.toU64 bucket.dataIndex) (key, newValue)
@Dict { buckets, data: newData, maxBucketCapacity, maxLoadFactor, shifts } @Dict { buckets, data: newData, maxBucketCapacity, maxLoadFactor, shifts }
Missing -> Err Missing ->
removeBucket (@Dict { buckets, data, maxBucketCapacity, maxLoadFactor, shifts }) bucketIndex removeBucket (@Dict { buckets, data, maxBucketCapacity, maxLoadFactor, shifts }) bucketIndex
Err KeyNotFound -> Err KeyNotFound ->
when alter Missing is when alter (Err Missing) is
Present newValue -> Ok newValue ->
if List.len data >= maxBucketCapacity then if List.len data >= maxBucketCapacity then
# Need to reallocate let regular insert handle that. # Need to reallocate let regular insert handle that.
insert (@Dict { buckets, data, maxBucketCapacity, maxLoadFactor, shifts }) key newValue insert (@Dict { buckets, data, maxBucketCapacity, maxLoadFactor, shifts }) key newValue
@ -556,7 +556,7 @@ update = \@Dict { buckets, data, maxBucketCapacity, maxLoadFactor, shifts }, key
distAndFingerprint = incrementDistN baseDistAndFingerprint (Num.toU32 dist) distAndFingerprint = incrementDistN baseDistAndFingerprint (Num.toU32 dist)
insertHelper buckets data bucketIndex distAndFingerprint key newValue maxBucketCapacity maxLoadFactor shifts insertHelper buckets data bucketIndex distAndFingerprint key newValue maxBucketCapacity maxLoadFactor shifts
Missing -> Err Missing ->
@Dict { buckets, data, maxBucketCapacity, maxLoadFactor, shifts } @Dict { buckets, data, maxBucketCapacity, maxLoadFactor, shifts }
circularDist = \start, end, size -> circularDist = \start, end, size ->
@ -1216,8 +1216,8 @@ expect
List.walk badKeys (Dict.empty {}) \acc, k -> List.walk badKeys (Dict.empty {}) \acc, k ->
Dict.update acc k \val -> Dict.update acc k \val ->
when val is when val is
Present p -> Present (p |> Num.addWrap 1) Ok p -> Ok (p |> Num.addWrap 1)
Missing -> Present 0 Err Missing -> Ok 0
allInsertedCorrectly = allInsertedCorrectly =
List.walk badKeys Bool.true \acc, k -> List.walk badKeys Bool.true \acc, k ->

View File

@ -1,29 +1,29 @@
procedure Dict.1 (Dict.730): procedure Dict.1 (Dict.731):
let Dict.739 : List {U32, U32} = Array []; let Dict.740 : List {U32, U32} = Array [];
let Dict.740 : List {[], []} = Array []; let Dict.741 : List {[], []} = Array [];
let Dict.741 : U64 = 0i64; let Dict.742 : U64 = 0i64;
let Dict.51 : Float32 = CallByName Dict.51; let Dict.51 : Float32 = CallByName Dict.51;
let Dict.52 : U8 = CallByName Dict.52; let Dict.52 : U8 = CallByName Dict.52;
let Dict.738 : {List {U32, U32}, List {[], []}, U64, Float32, U8} = Struct {Dict.739, Dict.740, Dict.741, Dict.51, Dict.52}; let Dict.739 : {List {U32, U32}, List {[], []}, U64, Float32, U8} = Struct {Dict.740, Dict.741, Dict.742, Dict.51, Dict.52};
ret Dict.739;
procedure Dict.4 (Dict.737):
let Dict.163 : List {[], []} = StructAtIndex 1 Dict.737;
let #Derived_gen.0 : List {U32, U32} = StructAtIndex 0 Dict.737;
dec #Derived_gen.0;
let Dict.738 : U64 = CallByName List.6 Dict.163;
dec Dict.163;
ret Dict.738; ret Dict.738;
procedure Dict.4 (Dict.736):
let Dict.163 : List {[], []} = StructAtIndex 1 Dict.736;
let #Derived_gen.0 : List {U32, U32} = StructAtIndex 0 Dict.736;
dec #Derived_gen.0;
let Dict.737 : U64 = CallByName List.6 Dict.163;
dec Dict.163;
ret Dict.737;
procedure Dict.51 (): procedure Dict.51 ():
let Dict.745 : Float32 = 0.8f64; let Dict.746 : Float32 = 0.8f64;
ret Dict.745; ret Dict.746;
procedure Dict.52 (): procedure Dict.52 ():
let Dict.743 : U8 = 64i64; let Dict.744 : U8 = 64i64;
let Dict.744 : U8 = 3i64; let Dict.745 : U8 = 3i64;
let Dict.742 : U8 = CallByName Num.75 Dict.743 Dict.744; let Dict.743 : U8 = CallByName Num.75 Dict.744 Dict.745;
ret Dict.742; ret Dict.743;
procedure List.6 (#Attr.2): procedure List.6 (#Attr.2):
let List.625 : U64 = lowlevel ListLenU64 #Attr.2; let List.625 : U64 = lowlevel ListLenU64 #Attr.2;

File diff suppressed because it is too large Load Diff