|
| 1 | +{-# OPTIONS_GHC -fno-warn-unused-imports #-} |
| 2 | + |
| 3 | +{-| |
| 4 | +Sets allow you to store *unique* elements, providing efficient insertion, |
| 5 | +lookups, and deletions. If you are storing sets of @Int@ s consider using |
| 6 | +'Data.IntSet' from the <https://hackage.haskell.org/packages/containers containers> package. You can find the |
| 7 | +introductory documentation for @containers@ at |
| 8 | +<https://haskell-containers.readthedocs.io>. |
| 9 | +
|
| 10 | +@ |
| 11 | +data HashSet element = ... |
| 12 | +@ |
| 13 | +
|
| 14 | +
|
| 15 | +All of these implementations are *immutable* which means that any update |
| 16 | +functions do not modify the set that you passed in, they creates a new set. In |
| 17 | +order to keep the changes you need to assign it to a new variable. For example: |
| 18 | +
|
| 19 | +@ |
| 20 | +let s1 = HashSet.fromList ["a", "b"] |
| 21 | +let s2 = HashSet.delete "a" s1 |
| 22 | +print s1 |
| 23 | +> fromList ["a","b"] |
| 24 | +print s2 |
| 25 | +> fromList ["b"] |
| 26 | +@ |
| 27 | +
|
| 28 | +__IMPORTANT:__ @HashSet@ relies on the @element@ type having instances of the @Eq@ and |
| 29 | + @Hashable@ typeclasses for its internal representation. These are already |
| 30 | + defined for builtin types, and if you are using your own data type you can |
| 31 | + use the |
| 32 | + <https://en.wikibooks.org/wiki/Haskell/Classes_and_types#Deriving deriving> |
| 33 | + mechanism. |
| 34 | +
|
| 35 | +
|
| 36 | +-} |
| 37 | + |
| 38 | +module Tutorial.HashSet ( |
| 39 | + -- * Short Example |
| 40 | + -- $shortexample |
| 41 | + |
| 42 | + ) where |
| 43 | + |
| 44 | + |
| 45 | +{- $shortexample |
| 46 | +
|
| 47 | +The following GHCi session shows some of the basic set functionality: |
| 48 | +
|
| 49 | +@ |
| 50 | +import qualified Data.HashSet as HashSet |
| 51 | +
|
| 52 | +let dataStructures = HashSet.fromList ["HashSet", "HashMap", "Graph"] |
| 53 | +
|
| 54 | +-- Check if "HashMap" and "Trie" are in the set of data structures. |
| 55 | +HashSet.member "HashMap" dataStructures |
| 56 | +> True |
| 57 | +
|
| 58 | +HashSet.member "Trie" dataStructures |
| 59 | +> False |
| 60 | +
|
| 61 | +
|
| 62 | +-- Add "Trie" to our original set of data structures. |
| 63 | +let moreDataStructures = HashSet.insert "Trie" dataStructures |
| 64 | +
|
| 65 | +HashSet.member "Trie" moreDataStructures |
| 66 | +> True |
| 67 | +
|
| 68 | +
|
| 69 | +-- Remove "Graph" from our original set of data structures. |
| 70 | +let fewerDataStructures = HashSet.delete "Graph" dataStructures |
| 71 | +
|
| 72 | +HashSet.toList fewerDataStructures |
| 73 | +> ["HashSet", "HashMap"] |
| 74 | +
|
| 75 | +
|
| 76 | +-- Create a new set and combine it with our original set. |
| 77 | +let orderedDataStructures = HashSet.fromList ["Set", "Map"] |
| 78 | +
|
| 79 | +HashSet.union dataStructures orderedDataStructures |
| 80 | +> fromList ["Map", "HashSet", "Graph", "HashMap", "Set"] |
| 81 | +@ |
| 82 | +
|
| 83 | +
|
| 84 | +__TIP__: You can use the `OverloadedLists |
| 85 | + <https://ghc.haskell.org/trac/ghc/wiki/OverloadedLists>`_ extension so |
| 86 | + you don't need to write ``fromList [1, 2, 3]`` everywhere. Instead you |
| 87 | + can just write ``[1, 2, 3]`` and if the function is expecting a set it |
| 88 | + will be converted automatically! The code here will continue to use |
| 89 | + ``fromList`` for clarity though. |
| 90 | +
|
| 91 | +
|
| 92 | +-} |
0 commit comments