Skip to content

Commit 549d22b

Browse files
authored
Document asymptotic optimality of Map.compose (#960)
1 parent fbade40 commit 549d22b

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

containers/src/Data/Map/Internal.hs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2154,7 +2154,7 @@ disjoint (Bin _ k _ l r) t
21542154
-- the other, by using the values of the former as keys for lookups
21552155
-- in the latter.
21562156
--
2157-
-- Complexity: \( O (n * \log(m)) \), where \(m\) is the size of the first argument
2157+
-- Complexity: \( O (n \log m) \), where \(m\) is the size of the first argument
21582158
--
21592159
-- > compose (fromList [('a', "A"), ('b', "B")]) (fromList [(1,'a'),(2,'b'),(3,'z')]) = fromList [(1,"A"),(2,"B")]
21602160
--
@@ -2166,6 +2166,22 @@ disjoint (Bin _ k _ l r) t
21662166
-- 'compose' that forced the values of the output 'Map'. This version does not
21672167
-- force these values.
21682168
--
2169+
-- ==== __Note on complexity__
2170+
--
2171+
-- This function is asymptotically optimal. Given @n :: Map a b, m :: Map b c@,
2172+
-- the composition essentially maps each @a@ in @n@ to @Maybe c@, since the
2173+
-- composed lookup yields either one of the @c@ in @m@ or @Nothing@. The number
2174+
-- of possible such mappings is \((|m| + 1) ^ {|n|}\).
2175+
-- We now follow a similar reasoning to the one for
2176+
-- [sorting](https://en.wikipedia.org/wiki/Comparison_sort#Number_of_comparisons_required_to_sort_a_list).
2177+
-- To distinguish between \(x\) possible values, we need
2178+
-- \( \lceil \log_2 x \rceil \) bits. Thus, we have a lower bound of
2179+
-- \(\log_2 \left((|m| + 1) ^{|n|} \right) = |n| \cdot \log_2 (|m| + 1)\) bits.
2180+
-- @Map@ lookups are comparison-based, and each comparison gives us at most
2181+
-- one bit of information: in the worst case we'll always be left with at least
2182+
-- half of the remaining possible values, meaning we need at least as many
2183+
-- comparisons as we need bits.
2184+
--
21692185
-- @since 0.6.3.1
21702186
compose :: Ord b => Map b c -> Map a b -> Map a c
21712187
compose bc !ab

0 commit comments

Comments
 (0)