diff --git a/src/trove/string-dict.scrbl b/src/trove/string-dict.scrbl index e1dd715..6a06822 100644 --- a/src/trove/string-dict.scrbl +++ b/src/trove/string-dict.scrbl @@ -30,6 +30,11 @@ (method-spec (name "has-key")) (method-spec (name "count")) (method-spec (name "unfreeze")) + (method-spec (name "merge")) + (method-spec (name "keys-list")) + (method-spec (name "map-keys")) + (method-spec (name "fold-keys")) + (method-spec (name "each-key")) ))) (data-spec (name "MutableStringDict") @@ -44,7 +49,13 @@ (method-spec (name "has-key-now")) (method-spec (name "count-now")) (method-spec (name "freeze")) - (method-spec (name "seal"))))) + (method-spec (name "seal")) + (method-spec (name "merge-now")) + (method-spec (name "keys-list-now")) + (method-spec (name "map-keys-now")) + (method-spec (name "fold-keys-now")) + (method-spec (name "each-key-now")) + ))) )) @docmodule["string-dict"]{ @@ -225,6 +236,102 @@ check: end } +@sd-method["merge" + #:contract (a-arrow (SD-of "a") (SD-of "a") (SD-of "a")) + #:args (list (list "self" #f) (list "other" #f)) + #:return (SD-of "a") +] + +Returns a new immutable string-dict that has the keys of both the original +string-dict and the @pyret{other} string-dict. If a key in the resulting +string-dict occurs in only one of the input string-dicts, its value is taken +from that string-dict. If the key occurs in both input string-dicts, its value +is taken from the @pyret{other} string-dict. + +@examples{ +check: + sd1 = [string-dict: "a", 5, "c", 4] + sd2 = [string-dict: "a", 10, "b", 6] + sd3 = sd1.merge(sd2) + sd3 is [string-dict: "a", 10, "b", 6, "c", 4] + sd4 = sd2.merge(sd1) + sd4 is [string-dict: "a", 5, "b", 6, "c", 4] + # sd3 is different from sd4 + sd3 is-not sd4 + # merging the same dict a second time has no additional effect + sd2.merge(sd1).merge(sd1) is sd2.merge(sd1) +end +} + +@sd-method["keys-list" + #:contract (a-arrow (SD-of "a") (L-of S)) + #:args (list (list "self" #f)) + #:return (L-of S) +] + +Returns the list of keys in the immutable string-dict, in some unspecified order. + +@examples{ +check: + sd2 = [string-dict: "a", 10, "b", 6] + sd2.keys-list().sort() is [list: "a", "b"] +end +} + +@sd-method["map-keys" + #:contract (a-arrow (SD-of "a") (a-arrow "a" "b") (L-of "b")) + #:args (list (list "self" #f) (list "f" #f)) + #:return (L-of "b") +] + +Applies the function @pyret{f} to each key in the immutable string-dict, and +returns a list of the returned values in some unspecified order. + +@examples{ +check: + sd2 = [string-dict: "a", 10, "b", 6] + sd2.map-keys(lam(x): string-append(x, x) end) is%(lam(lft, rt): rt.member(lft) end) + [list: [list: "aa", "bb"], [list: "bb", "aa"]] +end +} + +@sd-method["fold-keys" + #:contract (a-arrow (SD-of "a") (a-arrow S "b") "b") + #:args (list (list "self" #f) (list "f" #f) (list "init" #f)) + #:return "b" +] + +Returns the result of folding the function @pyret{f} across the keys in the +immutable string-dict, in some unspecified order, starting with @pyret{init} as +the base value. + +@examples{ +check: + sd2 = [string-dict: "a", 10, "b", 6] + sd2.fold-keys(lam(x, acc): acc + string-length(x) end, 0) is 2 +end +} + +@sd-method["each-key" + #:contract (a-arrow (SD-of "a") (a-arrow S No) No) + #:args (list (list "self" #f) (list "f" #f)) + #:return No +] + +Calls the function @pyret{f} on each key in the immutable string-dict, +returning nothing. Use @pyret{each-key} instead of @pyret{map-keys} +when the function @pyret{f} is used only for its side-effects. + +@examples{ +var numkeys = 0 + +check: + sd2 = [string-dict: "a", 10, "b", 6] + sd2.each-key(lam(x): numkeys := numkeys + 1 end) is nothing + numkeys is 2 +end +} + @section{The MutableStringDict Type} @type-spec["MutableStringDict" (list "a")] @@ -423,4 +530,101 @@ check: end } +@msd-method["merge-now" + #:contract (a-arrow (MSD-of "a") (MSD-of "a") No) + #:args (list (list "self" #f) (list "other" #f)) + #:return No +] + +Modifies the mutable string-dict to include the keys from the @pyret{other} +mutable-string-dict. If a key occurs originally in only of the string-dicts, its final +value is taken from that string-dict. If a key occurs originally in both +the string-dicts, its value is taken from the @pyret{other} string-dict. +@pyret{merge-now} returns nothing. + +@examples{ +check: + msd1 = [mutable-string-dict: "a", 5, "c", 4] + msd2 = [mutable-string-dict: "a", 10, "b", 6] + msd1.get-value-now("a") is 5 + msd1.get-value-now("b") raises "Key b not found" + msd1.get-value-now("c") is 4 + msd1.merge-now(msd2) is nothing + # msd1 already had key "a", but updates its new value from msd2 + msd1.get-value-now("a") is 10 + # msd1 did not have key "b", so gets it from msd2 + msd1.get-value-now("b") is 6 + # msd2 doesn't have key "c", so msd1 keeps its value for "c" + msd1.get-value-now("c") is 4 +end +} + +@msd-method["keys-list-now" + #:contract (a-arrow (MSD-of "a") (L-of S)) + #:args (list (list "self" #f)) + #:return (L-of S) +] + +Returns the list of keys in the mutable string-dict, in some unspeicified order. + +@examples{ +check: + msd2 = [mutable-string-dict: "a", 10, "b", 6] + msd2.keys-list-now().sort() is [list: "a", "b"] +end +} + +@msd-method["map-keys-now" + #:contract (a-arrow (MSD-of "a") (a-arrow "a" "b") (L-of "b")) + #:args (list (list "self" #f) (list "f" #f)) + #:return (L-of "b") +] + +Applies the function @pyret{f} to each key in the mutable-string-dict, +and returns a list of the returned values in some unspecified order. + +@examples{ +check: + msd2 = [mutable-string-dict: "a", 10, "b", 6] + msd2.map-keys-now(lam(x): string-append(x, x) end) is%(lam(lft, rt): rt.member(lft) end) + [list: [list: "aa", "bb"], [list: "bb", "aa"]] +end +} + +@msd-method["fold-keys-now" + #:contract (a-arrow (MSD-of "a") (a-arrow S "b") "b") + #:args (list (list "self" #f) (list "f" #f) (list "init" #f)) + #:return "b" +] + +Returns the result of folding the function @pyret{f} across the keys in the +mutable string-dict, in some unspecified order, starting with @pyret{init} as +the base value. + +@examples{ +check: + msd2 = [mutable-string-dict: "a", 10, "b", 6] + msd2.fold-keys-now(lam(x, acc): acc + string-length(x) end, 0) is 2 +end +} + +@msd-method["each-key-now" + #:contract (a-arrow (MSD-of "a") (a-arrow S No) No) + #:args (list (list "self" #f) (list "f" #f)) + #:return No +] + +Calls the function @pyret{f} on each key in the mutable string-dict, +returning nothing. Use @pyret{each-key-now} instead of @pyret{map-keys-now} +when the function @pyret{f} is used only for its side-effects. + +@examples{ +var numkeys = 0 + +check: + msd2 = [mutable-string-dict: "a", 10, "b", 6] + msd2.each-key-now(lam(x): numkeys := numkeys + 1 end) is nothing + numkeys is 2 +end +} }