Maps in Standard ML
Maps are Standard ML’s built-in associative data type, sometimes called dictionaries in other languages.
To create an empty map, use an association list [ (key1, val1), (key2, val2) ]
.
(* Creating an empty list (used as a map) *)
val m = ref ([] : (string * int) list)
Set key/value pairs using typical (name, key) :: map
syntax.
(* Setting key/value pairs *)
val () = m := ("k1", 7) :: !m
val () = m := ("k2", 13) :: !m
Printing a map will show all of its key/value pairs.
(* Printing the map *)
val () = print ("map: " ^ concat (map (fn (k, v) => k ^ ":" ^ Int.toString(v) ^ " ") !m) ^ "\n")
Get a value for a key with List.find
.
(* Getting a value for a key *)
val v1 = List.find (fn (k, _) => k = "k1") (!m)
val () = (case v1 of SOME (_, v) => print ("v1: " ^ Int.toString(v) ^ "\n") | NONE => ())
If the key doesn’t exist, the zero value of the value type is returned.
(* Getting a key that doesn't exist *)
val v3 = List.find (fn (k, _) => k = "k3") (!m)
val () = (case v3 of SOME (_, v) => print ("v3: " ^ Int.toString(v) ^ "\n") | NONE => print "v3: 0\n")
The List.length
function returns the number of key/value pairs when called on a map.
(* Getting the length of the map *)
val () = print ("len: " ^ Int.toString (List.length (!m)) ^ "\n")
To remove a key/value pair, use List.filter
.
(* Deleting a key/value pair *)
val () = m := List.filter (fn (k, _) => k <> "k2") (!m)
val () = print ("map: " ^ concat (map (fn (k, v) => k ^ ":" ^ Int.toString(v) ^ " ") !m) ^ "\n")
To remove all key/value pairs from a map, simply set it to an empty list.
(* Clearing all key/value pairs *)
val () = m := []
val () = print ("map: " ^ concat (map (fn (k, v) => k ^ ":" ^ Int.toString(v) ^ " ") !m) ^ "\n")
You can also declare and initialize a new map in the same line with association list syntax.
(* Initializing and printing a new map *)
val n = [("foo", 1), ("bar", 2)]
val () = print ("map: " ^ concat (map (fn (k, v) => k ^ ":" ^ Int.toString(v) ^ " ") n) ^ "\n")
To check if two maps are equal, you can use the List.all
function.
(* Checking if two maps are equal *)
val n2 = [("foo", 1), ("bar", 2)]
val equal = List.all (fn (k, v) => List.exists (fn (k2, v2) => k = k2 andalso v = v2) n) n2 andalso
List.all (fn (k, v) => List.exists (fn (k2, v2) => k = k2 andalso v = v2) n2) n
val () = if equal then print ("n == n2\n") else ()
Note that maps appear as a printed list of key/value tuples when printed with print
.
Running the program will output:
map: k2:13 k1:7
v1: 7
v3: 0
len: 2
map: k1:7
map:
prs: false
map: bar:2 foo:1
n == n2
Now that we can run and build basic Standard ML programs, let’s learn more about the language.