Skip to content

Commit 5e2c6e1

Browse files
committed
Add HashDict.t type
1 parent e896e31 commit 5e2c6e1

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

lib/elixir/lib/hash_dict.ex

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ defmodule HashDict do
5454
contract_on: @contract_load,
5555
root: @node_template
5656

57+
58+
@typep ordered :: {HashDict, size :: non_neg_integer, [{key :: term, value :: term}]}
59+
@typep trie :: {HashDict, size :: non_neg_integer, depth :: non_neg_integer,
60+
expand_on :: non_neg_integer, contract_on :: non_neg_integer,
61+
root :: tuple}
62+
@opaque t :: ordered | trie
63+
5764
import Bitwise
5865

5966
# Let's inline common instructions
@@ -62,6 +69,7 @@ defmodule HashDict do
6269
@doc """
6370
Creates a new empty dict.
6471
"""
72+
@spec new :: t
6573
def new do
6674
ordered()
6775
end
@@ -75,6 +83,7 @@ defmodule HashDict do
7583
#=> HashDict[a: 1, b: 2]
7684
7785
"""
86+
@spec new([{term :: term, value :: term}]) :: t
7887
def new(pairs) do
7988
Enum.reduce pairs, ordered(), fn { k, v }, dict ->
8089
put(dict, k, v)
@@ -91,6 +100,7 @@ defmodule HashDict do
91100
#=> HashDict[{ "a", "a" }, { "b", "b" }]
92101
93102
"""
103+
@spec new(list, (term -> {key :: term, key :: term})) :: t
94104
def new(list, transform) when is_function(transform) do
95105
Enum.reduce list, new(), fn i, dict ->
96106
{ k, v } = transform.(i)
@@ -101,6 +111,7 @@ defmodule HashDict do
101111
@doc """
102112
Puts the given key and value in the dict.
103113
"""
114+
@spec put(t, key :: term, value :: term) :: t
104115
def put(dict, key, value) do
105116
{ dict, _ } = dict_put(dict, key, { :put, value })
106117
dict
@@ -110,6 +121,7 @@ defmodule HashDict do
110121
Puts the given value under key in the dictionary
111122
only if one does not exist yet.
112123
"""
124+
@spec put_new(t, key :: term, value :: term) :: t
113125
def put_new(dict, key, value) do
114126
update(dict, key, value, fn(v) -> v end)
115127
end
@@ -119,6 +131,7 @@ defmodule HashDict do
119131
to the given function. Raises if the key does
120132
not exist in the dictionary.
121133
"""
134+
@spec update(t, key :: term, (term -> term)) :: t
122135
def update(dict, key, fun) when is_function(fun, 1) do
123136
case dict_put(dict, key, { :update, nil, fun }) do
124137
{ dict, 0 } ->
@@ -133,6 +146,7 @@ defmodule HashDict do
133146
to the given function. Adds initial value if
134147
the key does not exist in the dicionary.
135148
"""
149+
@spec update(t, key :: term, initial :: term, (term -> term)) :: t
136150
def update(dict, key, initial, fun) when is_function(fun, 1) do
137151
{ dict, _ } = dict_put(dict, key, { :update, initial, fun })
138152
dict
@@ -141,6 +155,8 @@ defmodule HashDict do
141155
@doc """
142156
Gets the value under key from the dict.
143157
"""
158+
@spec get(t, key :: term) :: term
159+
@spec get(t, key :: term, default :: term) :: term
144160
def get(dict, key, default // nil) do
145161
case dict_get(dict, key) do
146162
{ ^key, value } -> value
@@ -152,6 +168,7 @@ defmodule HashDict do
152168
Gets the value under key from the dict,
153169
raises KeyError if such key does not exist.
154170
"""
171+
@spec get!(t, key :: term) :: term | no_return
155172
def get!(dict, key) when is_tuple(dict) do
156173
case dict_get(dict, key) do
157174
{ ^key, value } -> value
@@ -162,13 +179,15 @@ defmodule HashDict do
162179
@doc """
163180
Checks if the dict has the given key.
164181
"""
182+
@spec has_key?(t, key :: term) :: boolean
165183
def has_key?(dict, key) do
166184
match? { ^key, _ }, dict_get(dict, key)
167185
end
168186

169187
@doc """
170188
Deletes a value from the dict.
171189
"""
190+
@spec delete(t, key :: term) :: t
172191
def delete(ordered(bucket: bucket, size: size) = dict, key) do
173192
case bucket_delete(bucket, key) do
174193
{ _, 0 } ->
@@ -201,20 +220,23 @@ defmodule HashDict do
201220
@doc """
202221
Returns the dict size.
203222
"""
223+
@spec size(t) :: non_neg_integer
204224
def size(dict) do
205225
elem(dict, 1)
206226
end
207227

208228
@doc """
209229
Returns an empty dict.
210230
"""
231+
@spec empty(t) :: t
211232
def empty(_) do
212233
ordered()
213234
end
214235

215236
@doc """
216237
Converts the dict to a list.
217238
"""
239+
@spec to_list(t) :: list({key :: term, value :: term})
218240
def to_list(ordered(bucket: bucket)) do
219241
bucket
220242
end
@@ -226,20 +248,24 @@ defmodule HashDict do
226248
@doc """
227249
Get all keys in the dict.
228250
"""
251+
@spec keys(t) :: list(key :: term)
229252
def keys(dict) do
230253
dict_fold(dict, [], fn { k, _ }, acc -> [k|acc] end)
231254
end
232255

233256
@doc """
234257
Get all values in the dict.
235258
"""
259+
@spec values(t) :: list(values :: term)
236260
def values(dict) do
237261
dict_fold(dict, [], fn { _, v }, acc -> [v|acc] end)
238262
end
239263

240264
@doc """
241265
Merges two dictionaries.
242266
"""
267+
@spec merge(t, t | Dict.t) :: t
268+
@spec merge(t, t | Dict.t, ((key :: term, value1 :: term, value2 :: term) -> value :: term)) :: t
243269
def merge(dict, enum, callback // fn(_k, _v1, v2) -> v2 end)
244270

245271
def merge(dict1, dict2, callback) when is_record(dict1, HashDict) and is_record(dict2, HashDict) and elem(dict1, 1) < elem(dict2, 1) do

0 commit comments

Comments
 (0)