HORIZON HASKELLDocslts/ghc-9.14.xd82dee82026-10-12Search names, modules, packages, or :: a typeCtrl K

GHC 9.14.1 · lts/ghc-9.14.x · d82dee8 · 2026-10-12

Modulebytestring-trie-0.2.7.7Haskell2010

Data.Trie.Internal

Internal definition of the Trie data type and generic functions for manipulating them. Almost everything here is re-exported from Data.Trie, which is the preferred API for users. This module is for developers who need deeper (and less stable) access to the abstract type.

  • 1 type
  • 40 values

Data types

1 declaration
datadata Trie a
#

A map from ByteStrings to a. For all the generic functions, note that tries are strict in the Maybe but not in a.

The Monad instance is strange. If a key k1 is a prefix of other keys, then results from binding the value at k1 will override values from longer keys when they collide. If this is useful for anything, or if there's a more sensible instance, I'd be curious to know.

Instances19Monad, Functor, Applicative, Foldable, Traversable, Eq1, …
  • Monad TrieDefined in bytestring-trie-0.2.7.7 · Data.Trie.Internal
  • Functor TrieDefined in bytestring-trie-0.2.7.7 · Data.Trie.Internal
  • Applicative TrieDefined in bytestring-trie-0.2.7.7 · Data.Trie.Internal
  • Foldable TrieDefined in bytestring-trie-0.2.7.7 · Data.Trie.Internal
  • Traversable TrieDefined in bytestring-trie-0.2.7.7 · Data.Trie.Internal
  • Eq1 TrieDefined in bytestring-trie-0.2.7.7 · Data.Trie.Internal
  • Ord1 TrieDefined in bytestring-trie-0.2.7.7 · Data.Trie.Internal

    Warning: This instance suffers unnecessarily from Bug #25.

  • Read1 TrieDefined in bytestring-trie-0.2.7.7 · Data.Trie.Internal
  • Show1 TrieDefined in bytestring-trie-0.2.7.7 · Data.Trie.Internal

    Warning: This instance suffers Bug #25.

  • IsList (Trie a)Defined in bytestring-trie-0.2.7.7 · Data.Trie.Internal

    Warning: The toList method of this instance suffers Bug #25.

  • Eq a => Eq (Trie a)Defined in bytestring-trie-0.2.7.7 · Data.Trie.Internal
  • Ord a => Ord (Trie a)Defined in bytestring-trie-0.2.7.7 · Data.Trie.Internal

    Warning: This instance suffers unnecessarily from Bug #25.

  • Read a => Read (Trie a)Defined in bytestring-trie-0.2.7.7 · Data.Trie.Internal
  • Show a => Show (Trie a)Defined in bytestring-trie-0.2.7.7 · Data.Trie.Internal

    Warning: This instance suffers Bug #25.

  • Semigroup a => Semigroup (Trie a)Defined in bytestring-trie-0.2.7.7 · Data.Trie.Internal
  • Monoid a => Monoid (Trie a)Defined in bytestring-trie-0.2.7.7 · Data.Trie.Internal
  • NFData a => NFData (Trie a)Defined in bytestring-trie-0.2.7.7 · Data.Trie.Internal
  • Binary a => Binary (Trie a)Defined in bytestring-trie-0.2.7.7 · Data.Trie.Internal
  • type Item (Trie a) = (ByteString, a)Defined in bytestring-trie-0.2.7.7 · Data.Trie.Internal

Performance Warning

Many (but not all) functions which need to reconstruct bytestrings suffer from an asymptotic slowdown; see: Bug #25. For clarity, all functions affected by this bug will have a link to this section. This is not a new bug, it has affected all prior versions of this library as well. However, compared to older versions, bytestring-trie-0.2.7 mitigates the severity of the bug, and in certain cases to avoids it entirely.

In particular, this affects the "keyed" variants of functions (for folding, traversing, filtering, etc), and anything built from them, including toListBy and various instances which use it.

Conversely, functions which are unaffected include: those like alterBy which merely pass the query back to the user as a convenience; those which only need to reconstruct a single bytestring (e.g., the priority-queue functions); and matches/matches_.

Basic functions

4 declarations
valueempty :: Trie a
#

\mathcal{O}(1). Construct the empty trie.

valuenull :: Trie a -> Bool
#

\mathcal{O}(1). Is the trie empty?

valuesize :: Trie a -> Int
#

\mathcal{O}(n). Get count of elements in trie.

List-conversion functions

4 declarations
valuefromList :: [(ByteString, a)] -> Trie a
#

Convert association list into a trie. On key conflict, values earlier in the list shadow later ones.

valuetoList :: Trie a -> [(ByteString, a)]
#

Convert trie into association list. The list is ordered according to the keys.

Warning: This function suffers Bug #25.

valuetoListBy :: (ByteString -> a -> b) -> Trie a -> [b]
#

Convert a trie into a list using a function. Resulting values are in key-sorted order.

Warning: This function suffers Bug #25.

valueelems :: Trie a -> [a]
#

Return all values in the trie, in key-sorted order.

Note: Prior to version 0.2.7, this function suffered Bug #25; but it no longer does.

Query functions

4 declarations
valuelookupBy_
  1. :: (a -> Trie a -> b)

    The query matches a value.

  2. -> (Trie a -> b)

    The query doesn't match, but an extension might.

  3. -> b

    The query doesn't match, nor does any extension.

  4. -> ByteString
  5. -> Trie a
  6. -> b
#

Generic function to find a value (if it exists) and the subtrie rooted at the prefix. The first function argument is called if and only if a node is exactly reachable by the query; if no node is exactly reachable the default value is used; if the middle of an arc is reached, the second function argument is used.

This function is intended for internal use. For the public-facing version, see lookupBy.

Note: Type changed in 0.2.7

valuematch_ :: Trie a -> ByteString -> Maybe (Int, a)
#

Given a query, find the longest prefix with an associated value in the trie, returning the length of that prefix and the associated value.

This function may not have the most useful return type. For a version that returns the prefix itself as well as the remaining string, see match.

valuematches_ :: Trie a -> ByteString -> [(Int, a)]
#

Given a query, find all prefixes with associated values in the trie, and return the length of each prefix with their value, in order from shortest prefix to longest. This function is a good producer for list fusion.

This function may not have the most useful return type. For a version that returns the prefix itself as well as the remaining string, see matches.

Simple modification

3 declarations
valueadjust :: (a -> a) -> ByteString -> Trie a -> Trie a
#

Apply a function to the value at a key. If the key is not present, then the trie is returned unaltered.

Combining tries

3 declarations
valuewip_unionWith :: (a -> a -> a) -> Trie a -> Trie a -> Trie a
#

Take the union of two tries, using a function to resolve conflicts. The resulting trie is constructed strictly, but the results of the combining function are evaluated lazily.

valuemergeBy :: (a -> a -> Maybe a) -> Trie a -> Trie a -> Trie a
#

Take the union of two tries, using a function to resolve collisions. This can only define the space of functions between union and symmetric difference but, with those two, all set operations can be defined (albeit inefficiently).

valueintersectBy :: (a -> b -> Maybe c) -> Trie a -> Trie b -> Trie c
#

Take the intersection of two tries, using a function to resolve collisions.

Priority-queue functions

4 declarations
valueminAssoc :: Trie a -> Maybe (ByteString, a)
#

Return the lexicographically smallest ByteString and the value it's mapped to; or Nothing for the empty trie. When one entry is a prefix of another, the prefix will be returned.

Note: Prior to version 0.2.7, this function suffered Bug #25; but it no longer does.

valuemaxAssoc :: Trie a -> Maybe (ByteString, a)
#

Return the lexicographically largest ByteString and the value it's mapped to; or Nothing for the empty trie. When one entry is a prefix of another, the longer one will be returned.

Note: Prior to version 0.2.7, this function suffered Bug #25; but it no longer does.

Mapping, filtering, folding, and traversing

0 declarations

Filterable

valuefilter :: (a -> Bool) -> Trie a -> Trie a
#

Retain only those values which satisfy some predicate.

Laws
Definition

filter f ≡ filterMap (\v -> v <$ guard (f v))

Composition

filter f . filter g ≡ filter (liftA2 (&&) f g)

The definition above is a special case of the fusion law for filterMap. (Also, the name just means definitional-equality; it's not the actual implementation used.)

valuefilterMap :: (a -> Maybe b) -> Trie a -> Trie b
#

Apply a function to all values, potentially removing them.

Laws
Fission

filterMap f ≡ fmap (fromJust . f) . filter (isJust . f)

Fusion

fmap f . filter g ≡ filterMap (\v -> f v <$ guard (g v))

Conservation

filterMap (Just . f) ≡ fmap f

Composition

filterMap f . filterMap g ≡ filterMap (f <=< g)

The fission/fusion laws are essentially the same, they differ only in which direction is more "natural" for use as a rewrite rule. The conservation law is just a special case of fusion, but it's a particularly helpful one to take note of.

Witherable

valuefilterA :: Applicative f => (a -> f Bool) -> Trie a -> f (Trie a)
#

An effectful version of filter.

Laws
Definition

filterA f ≡ wither (\v -> (v <$) . guard <$> f v)

Naturality

filterA (t . f) ≡ t . filterA f

, for any

applicative-transformation

t

Purity

filterA (pure . f) ≡ pure . filter f

Horizontal Composition

filterA f `under` filterA g ≡ filterA (underA2 (&&) f g)

, where

-- Like 'liftA2' for the @(a->)@ monad, but horizontal.
-- The function definition should (hopefully) be straightforward
-- to follow; however, do beware the oddly criss-crossed types
-- for @g@ and @f@.
underA2 :: (Applicative f, Applicative g)
        => (b -> c -> d)
        -> (a -> g b)
        -> (a -> f c)
        -> a -> Compose f g d
underA2 h g f = liftA2 (liftA2 h) (g `under` pure) (pure `under` f)

For the definition of under and more details about horizontal composition, see the laws section of wither.

valuewither :: Applicative f => (a -> f (Maybe b)) -> Trie a -> f (Trie b)
#

An effectful version of filterMap.

Laws
Naturality

wither (t . f) ≡ t . wither f

, for any

applicative-transformation

t

Purity

wither (pure . f) ≡ pure . filterMap f

Conservation

wither (fmap Just . f) ≡ traverse f

Horizontal Composition

wither f `under` wither g ≡ wither (wither_Maybe f `under` g)

, where:

under :: Functor f
      => (b -> g c)
      -> (a -> f b)
      -> a -> Compose f g c
under g f = Compose . fmap g . f

-- | Variant of wither for Maybe instead of Trie.
wither_Maybe :: Applicative f
             => (a -> f (Maybe b))
             -> Maybe a -> f (Maybe b)
wither_Maybe f = fmap join . traverse f

Note that the horizontal composition law is using two different applicative functors. Conversely, a vertical composition law would have the form: wither f <=< wither g ≡ ...; however, we cannot have such a law except when the applicative functor is in fact a commutative monad (i.e., the order of effects doesn't matter). For the curious, the terminology of "horizontal" composition vs "vertical" composition comes from category theory.

Although the horizontal composition law may look baroque, it is helpful to compare it to the composition law for traverse itself:

traverse f `under` traverse g ≡ traverse (f `under` g)

Contextual filtering/mapping functions

Foldable

valuecata_
  1. :: (ByteString -> Maybe a -> b -> b)

    Algebra for arc.

  2. -> (b -> b -> b)

    Algebra for binary branch.

  3. -> b

    Algebra for empty trie.

  4. -> Trie a
  5. -> b
#

Catamorphism for tries. Unlike most other functions (mapBy, contextualMapBy, foldrWithKey, etc), this function does not reconstruct the full ByteString for each value; instead it only returns the suffix since the previous value or branch point.

This function is a direct/literal catamorphism of the implementation datatype, erasing only some bitmasking metadata for the branches. For a more semantic catamorphism, see cata.

valuecata
  1. :: (ByteString -> a -> b -> b)

    Algebra for accepting arcs.

  2. -> (ByteString -> [b] -> b)

    Algebra for n-ary branch with prefix.

  3. -> b

    Algebra for empty trie.

  4. -> Trie a
  5. -> b
#

Catamorphism for tries. Unlike most other functions (mapBy, contextualMapBy, foldrWithKey, etc), this function does not reconstruct the full ByteString for each value; instead it only returns the suffix since the previous value or branch point.

This function is a semantic catamorphism; that is, it tries to express the invariants of the implementation, rather than exposing the literal structure of the implementation. For a more literal catamorphism, see cata_.

Traverse

Internal utility functions

2 declarations