-
Notifications
You must be signed in to change notification settings - Fork 101
Expand file tree
/
Copy pathHashSet.hs
More file actions
197 lines (138 loc) · 4.77 KB
/
Copy pathHashSet.hs
File metadata and controls
197 lines (138 loc) · 4.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-|
Sets allow you to store *unique* elements, providing efficient insertion,
lookups, and deletions. If you are storing sets of @Int@ s consider using
'Data.IntSet' from the <https://hackage.haskell.org/packages/containers containers> package. You can find the
introductory documentation for @containers@ at
<https://haskell-containers.readthedocs.io>.
@
data 'HashSet' element = ...
@
All of these implementations are /immutable/ which means that any update
functions do not modify the set that you passed in, they creates a new set. In
order to keep the changes you need to assign it to a new variable. For example:
@
import qualified Data.HashSet as HashSet
let s1 = HashSet.'HashSet.fromList' ["a", "b"]
let s2 = HashSet.'HashSet.delete' "a" s1
print s1
> HashSet.'HashSet.fromList' ["a","b"]
print s2
> HashSet.'HashSet.fromList' ["b"]
@
__IMPORTANT:__ @HashSet@ relies on the @element@ type having instances of the @Eq@ and
@Hashable@ typeclasses for its internal representation. These are already
defined for builtin types, and if you are using your own data type you can
use the
<https://en.wikibooks.org/wiki/Haskell/Classes_and_types#Deriving deriving>
mechanism.
-}
module Tutorial.HashSet (
-- * Short Example
-- $shortexample
-- * Importing HashSet
-- $importing
-- * Common API Functions
-- ** Construction and Conversion
-- *** Create an empty set
-- $empty
-- *** Create a set with one element (singleton)
-- $singleton
-- *** Create a set from a list
-- $fromlist
-- * Continue reading
-- $continuereading
) where
import qualified Data.HashSet as HashSet
{- $shortexample
The following GHCi session shows some of the basic set functionality:
@
import qualified Data.HashSet as HashSet
let dataStructures = HashSet.'HashSet.fromList' [\"HashSet\", \"HashMap\", \"Graph\"]
-- Check if HashMap and Trie are in the set of data structures.
HashSet.'HashSet.member' \"HashMap\" dataStructures
> True
HashSet.'HashSet.member' "Trie" dataStructures
> False
-- Add Trie to our original set of data structures.
let moreDataStructures = HashSet.'HashSet.insert' \"Trie\" dataStructures
HashSet.'HashSet.member' \"Trie\" moreDataStructures
> True
-- Remove Graph from our original set of data structures.
let fewerDataStructures = HashSet.'HashSet.delete' \"Graph\" dataStructures
HashSet.'HashSet.toList' fewerDataStructures
> [\"HashSet\", \"HashMap\"]
-- Create a new set and combine it with our original set.
let orderedDataStructures = HashSet.'HashSet.fromList' [\"Set\", \"Map\"]
HashSet.'HashSet.union' dataStructures orderedDataStructures
> fromList [\"Map\", \"HashSet\", \"Graph\", \"HashMap\", \"Set\"]
@
__TIP__: You can use the
<https://ghc.haskell.org/trac/ghc/wiki/OverloadedLists OverloadedLists>
extension so you don't need to write `fromList [1, 2, 3]` everywhere.
Instead you can just write `[1, 2, 3]` and if the function is expecting
a set it will be converted automatically! The code here will continue
to use `fromList` for clarity though.
-}
{- $importing
When using HashSet in a Haskell source file you should always use a `qualified`
import because these modules export names that clash with the standard Prelude.
You can import the type constructor unqualified.
@
import Data.HashSet (HashSet)
import qualified Data.HashSet as HashSet
@
-}
{- $commonapifunctions
.. TIP::
All of these functions that work for `HashSet` will also work for
`IntSet`, which has the element type `a` specialized to `Int`. Anywhere
that you see `HashSet Int` you can replace it with `IntSet`. This will
speed up most operations tremendously (see `Performance`_) with the exception
of `size` which is O(1) for `HashSet` and O(n) for `IntSet`.
.. NOTE::
`fromList [some,list,elements]` is how a `HashSet` is printed.
-}
{- $empty
@
HashSet.empty :: HashSet a
HashSet.empty = ...
@
`HashSet.empty' creates a set with zero elements.
@
HashSet.empty
> fromList []
@
-}
{- $singleton
@
HashSet.singleton :: a -> HashSet a
HashSet.singleton x = ...
@
'HashSet.singleton' creates a set with a single element
`x` in it.
@
HashSet.singleton "containers"
> fromList ["containers"]
HashSet.singleton 1
> fromList [1]
@
-}
{- $fromlist
@
HashSet.fromList :: [a] -> HashSet a
HashSet.fromList xs = ...
@
'HashSet.fromList' creates a set containing the elements of the
list `xs`. Since sets don't contain duplicates, if there are repeated elements
in the list they will only appear once.
@
HashSet.fromList ["base", "containers", "QuickCheck"]
> fromList [,"containers","base","QuickCheck"]
HashSet.fromList [1, 1, 2, 3, 4, 4, 5, 1]
> fromList [1,2,3,4,5]
@
-}
{- $continuereading
Continue the tutorial at "Tutorial.HashMap".
-}