|
15 | 15 |
|
16 | 16 | -- Portability : portable
|
17 | 17 | --
|
18 |
| --- An efficient implementation of maps from integer keys to values |
19 |
| --- (dictionaries). |
20 | 18 | --
|
21 |
| --- API of this module is strict in both the keys and the values. |
22 |
| --- If you need value-lazy maps, use "Data.IntMap.Lazy" instead. |
23 |
| --- The 'IntMap' type itself is shared between the lazy and strict modules, |
24 |
| --- meaning that the same 'IntMap' value can be passed to functions in |
25 |
| --- both modules (although that is rarely needed). |
| 19 | +-- = Finite Int Maps (strict interface) |
26 | 20 | --
|
27 |
| --- These modules are intended to be imported qualified, to avoid name |
28 |
| --- clashes with Prelude functions, e.g. |
| 21 | +-- The @'IntMap' v@ type represents a finite map (sometimes called a dictionary) |
| 22 | +-- from key of type @Int@ to values of type @v@. |
29 | 23 | --
|
30 |
| --- > import Data.IntMap.Strict (IntMap) |
31 |
| --- > import qualified Data.IntMap.Strict as IntMap |
| 24 | +-- Each function in this module is careful to force values before installing |
| 25 | +-- them in a 'Map'. This is usually more efficient when laziness is not |
| 26 | +-- necessary. When laziness /is/ required, use the functions in |
| 27 | +-- "Data.IntMap.Lazy". |
| 28 | +-- |
| 29 | +-- In particular, the functions in this module obey the following law: |
| 30 | +-- |
| 31 | +-- - If all values stored in all maps in the arguments are in WHNF, then all |
| 32 | +-- values stored in all maps in the results will be in WHNF once those maps |
| 33 | +-- are evaluated. |
| 34 | +-- |
| 35 | +-- For a walkthrough of the most commonly used functions see the |
| 36 | +-- <https://haskell-containers.readthedocs.io/en/latest/map.html maps introduction>. |
| 37 | +-- |
| 38 | +-- This module is intended to be imported qualified, to avoid name clashes with |
| 39 | +-- Prelude functions: |
| 40 | +-- |
| 41 | +-- > import Data.IntMap.Strict (IntMap) |
| 42 | +-- > import qualified Data.IntMap.Strict as IntMap |
| 43 | +-- |
| 44 | +-- Note that the implementation is generally /left-biased/. Functions that take |
| 45 | +-- two maps as arguments and combine them, such as `union` and `intersection`, |
| 46 | +-- prefer the values in the first argument to those in the second. |
| 47 | +-- |
| 48 | +-- |
| 49 | +-- == Detailed performance information |
| 50 | +-- |
| 51 | +-- The amortized running time is given for each operation, with /n/ referring to |
| 52 | +-- the number of entries in the map and /W/ referring to the number of bits in |
| 53 | +-- an 'Int' (32 or 64). |
| 54 | +-- |
| 55 | +-- Benchmarks comparing "Data.IntMap.Strict" with other dictionary |
| 56 | +-- implementations can be found at https://github.com/haskell-perf/dictionaries. |
| 57 | +-- |
| 58 | +-- |
| 59 | +-- == Warning |
| 60 | +-- |
| 61 | +-- The 'IntMap' type is shared between the lazy and strict modules, meaning that |
| 62 | +-- the same 'IntMap' value can be passed to functions in both modules. This |
| 63 | +-- means that the 'Functor', 'Traversable' and 'Data' instances are the same as |
| 64 | +-- for the "Data.IntMap.Lazy" module, so if they are used the resulting map may |
| 65 | +-- contain suspended values (thunks). |
| 66 | +-- |
| 67 | +-- |
| 68 | +-- == Implementation |
32 | 69 | --
|
33 | 70 | -- The implementation is based on /big-endian patricia trees/. This data
|
34 |
| --- structure performs especially well on binary operations like 'union' |
35 |
| --- and 'intersection'. However, my benchmarks show that it is also |
36 |
| --- (much) faster on insertions and deletions when compared to a generic |
37 |
| --- size-balanced map implementation (see "Data.Map"). |
| 71 | +-- structure performs especially well on binary operations like 'union' and |
| 72 | +-- 'intersection'. Additionally, benchmarks show that it is also (much) faster |
| 73 | +-- on insertions and deletions when compared to a generic size-balanced map |
| 74 | +-- implementation (see "Data.Map"). |
38 | 75 | --
|
39 | 76 | -- * Chris Okasaki and Andy Gill, \"/Fast Mergeable Integer Maps/\",
|
40 | 77 | -- Workshop on ML, September 1998, pages 77-86,
|
|
44 | 81 | -- Information Coded In Alphanumeric/\", Journal of the ACM, 15(4),
|
45 | 82 | -- October 1968, pages 514-534.
|
46 | 83 | --
|
47 |
| --- Operation comments contain the operation time complexity in |
48 |
| --- the Big-O notation <http://en.wikipedia.org/wiki/Big_O_notation>. |
49 |
| --- Many operations have a worst-case complexity of /O(min(n,W))/. |
50 |
| --- This means that the operation can become linear in the number of |
51 |
| --- elements with a maximum of /W/ -- the number of bits in an 'Int' |
52 |
| --- (32 or 64). |
53 |
| --- |
54 |
| --- Be aware that the 'Functor', 'Traversable' and 'Data' instances |
55 |
| --- are the same as for the "Data.IntMap.Lazy" module, so if they are used |
56 |
| --- on strict maps, the resulting maps will be lazy. |
57 | 84 | -----------------------------------------------------------------------------
|
58 | 85 |
|
59 | 86 | -- See the notes at the beginning of Data.IntMap.Internal.
|
60 | 87 |
|
61 | 88 | module Data.IntMap.Strict (
|
62 |
| - -- * Strictness properties |
63 |
| - -- $strictness |
64 |
| - |
65 | 89 | -- * Map type
|
66 | 90 | #if !defined(TESTING)
|
67 | 91 | IntMap, Key -- instance Eq,Show
|
@@ -310,24 +334,6 @@ import Data.Functor((<$>))
|
310 | 334 | #endif
|
311 | 335 | import Control.Applicative (Applicative (..), liftA2)
|
312 | 336 |
|
313 |
| --- $strictness |
314 |
| --- |
315 |
| --- This module satisfies the following strictness properties: |
316 |
| --- |
317 |
| --- 1. Key arguments are evaluated to WHNF; |
318 |
| --- |
319 |
| --- 2. Keys and values are evaluated to WHNF before they are stored in |
320 |
| --- the map. |
321 |
| --- |
322 |
| --- Here's an example illustrating the first property: |
323 |
| --- |
324 |
| --- > delete undefined m == undefined |
325 |
| --- |
326 |
| --- Here are some examples that illustrate the second property: |
327 |
| --- |
328 |
| --- > map (\ v -> undefined) m == undefined -- m is not empty |
329 |
| --- > mapKeys (\ k -> undefined) m == undefined -- m is not empty |
330 |
| - |
331 | 337 | {--------------------------------------------------------------------
|
332 | 338 | Query
|
333 | 339 | --------------------------------------------------------------------}
|
|
0 commit comments