packages feed

generic-trie 0.3.1 → 0.3.2

raw patch · 6 files changed

+439/−57 lines, 6 filesdep +generic-triedep ~basedep ~transformersnew-component:exe:bogusnew-uploaderPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: generic-trie

Dependency ranges changed: base, transformers

API changes (from Hackage documentation)

- Data.GenericTrie.Internal: instance (GHC.Show.Show a, Data.GenericTrie.Internal.TrieKey k) => GHC.Show.Show (Data.GenericTrie.Internal.Trie k a)
- Data.GenericTrie.Internal: instance (GHC.Show.Show k, GHC.Classes.Ord k) => Data.GenericTrie.Internal.TrieKey (Data.GenericTrie.Internal.OrdKey k)
- Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.TrieKey GHC.Integer.Type.Integer
- Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.TrieKey k => Data.GenericTrie.Internal.GTrieKeyShow (GHC.Generics.K1 i k)
- Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.TrieKey k => Data.GenericTrie.Internal.TrieKey (GHC.Base.Maybe k)
- Data.GenericTrie.Internal: type family TrieRep k :: * -> *;
+ Data.GenericTrie: class TrieKey k => ShowTrieKey k
+ Data.GenericTrie: traverseMaybeWithKey :: (TrieKey k, Applicative f) => (k -> a -> f (Maybe b)) -> Trie k a -> f (Trie k b)
+ Data.GenericTrie.Internal: -- | Type of the representation of tries for this key.
+ Data.GenericTrie.Internal: class TrieKey k => ShowTrieKey k
+ Data.GenericTrie.Internal: data family GTrie f a
+ Data.GenericTrie.Internal: genericAlter :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k) => k -> (Maybe a -> Maybe a) -> Trie k a -> Trie k a
+ Data.GenericTrie.Internal: genericTraverseMaybeWithKey :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k, Applicative f) => (k -> a -> f (Maybe b)) -> Trie k a -> f (Trie k b)
+ Data.GenericTrie.Internal: gtraverseMaybeWithKey :: (GTrieKey f, Applicative m) => (f p -> a -> m (Maybe b)) -> GTrie f a -> m (Maybe (GTrie f b))
+ Data.GenericTrie.Internal: gtrieAlter :: GTrieKey f => f p -> (Maybe a -> Maybe a) -> GTrie f a -> Maybe (GTrie f a)
+ Data.GenericTrie.Internal: instance (Data.GenericTrie.Internal.ShowTrieKey a, Data.GenericTrie.Internal.ShowTrieKey b) => Data.GenericTrie.Internal.ShowTrieKey (Data.Either.Either a b)
+ Data.GenericTrie.Internal: instance (Data.GenericTrie.Internal.ShowTrieKey a, Data.GenericTrie.Internal.ShowTrieKey b) => Data.GenericTrie.Internal.ShowTrieKey (a, b)
+ Data.GenericTrie.Internal: instance (Data.GenericTrie.Internal.ShowTrieKey a, Data.GenericTrie.Internal.ShowTrieKey b, Data.GenericTrie.Internal.ShowTrieKey c) => Data.GenericTrie.Internal.ShowTrieKey (a, b, c)
+ Data.GenericTrie.Internal: instance (Data.GenericTrie.Internal.ShowTrieKey a, Data.GenericTrie.Internal.ShowTrieKey b, Data.GenericTrie.Internal.ShowTrieKey c, Data.GenericTrie.Internal.ShowTrieKey d) => Data.GenericTrie.Internal.ShowTrieKey (a, b, c, d)
+ Data.GenericTrie.Internal: instance (Data.GenericTrie.Internal.ShowTrieKey a, Data.GenericTrie.Internal.ShowTrieKey b, Data.GenericTrie.Internal.ShowTrieKey c, Data.GenericTrie.Internal.ShowTrieKey d, Data.GenericTrie.Internal.ShowTrieKey e) => Data.GenericTrie.Internal.ShowTrieKey (a, b, c, d, e)
+ Data.GenericTrie.Internal: instance (Data.GenericTrie.Internal.TrieKey k, GHC.Show.Show k, GHC.Show.Show a) => GHC.Show.Show (Data.GenericTrie.Internal.Trie k a)
+ Data.GenericTrie.Internal: instance (GHC.Show.Show k, GHC.Classes.Ord k) => Data.GenericTrie.Internal.ShowTrieKey (Data.GenericTrie.Internal.OrdKey k)
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.ShowTrieKey ()
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.ShowTrieKey Data.Void.Void
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.ShowTrieKey GHC.Num.Integer.Integer
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.ShowTrieKey GHC.Num.Natural.Natural
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.ShowTrieKey GHC.Types.Bool
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.ShowTrieKey GHC.Types.Char
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.ShowTrieKey GHC.Types.Int
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.ShowTrieKey GHC.Types.Ordering
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.ShowTrieKey GHC.Types.Word
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.ShowTrieKey k => Data.GenericTrie.Internal.GTrieKeyShow (GHC.Generics.K1 i k)
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.ShowTrieKey k => Data.GenericTrie.Internal.ShowTrieKey (GHC.Maybe.Maybe k)
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.ShowTrieKey k => Data.GenericTrie.Internal.ShowTrieKey [k]
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.TrieKey Data.Void.Void
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.TrieKey GHC.Num.Integer.Integer
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.TrieKey GHC.Num.Natural.Natural
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.TrieKey GHC.Types.Ordering
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.TrieKey GHC.Types.Word
+ Data.GenericTrie.Internal: instance Data.GenericTrie.Internal.TrieKey k => Data.GenericTrie.Internal.TrieKey (GHC.Maybe.Maybe k)
+ Data.GenericTrie.Internal: instance GHC.Classes.Ord k => Data.GenericTrie.Internal.TrieKey (Data.GenericTrie.Internal.OrdKey k)
+ Data.GenericTrie.Internal: toList :: TrieKey k => Trie k a -> [(k, a)]
+ Data.GenericTrie.Internal: trieAlter :: (TrieKey k, GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k) => k -> (Maybe a -> Maybe a) -> Trie k a -> Trie k a
+ Data.GenericTrie.Internal: trieTraverseMaybeWithKey :: (TrieKey k, GTrieKey (Rep k), TrieRep k ~ TrieRepDefault k, Generic k, Applicative f) => (k -> a -> f (Maybe b)) -> Trie k a -> f (Trie k b)
- Data.GenericTrie.Internal: MkTrie :: (TrieRep k a) -> Trie k a
+ Data.GenericTrie.Internal: MkTrie :: TrieRep k a -> Trie k a
- Data.GenericTrie.Internal: genericEmpty :: (TrieRep k ~ TrieRepDefault k) => Trie k a
+ Data.GenericTrie.Internal: genericEmpty :: TrieRep k ~ TrieRepDefault k => Trie k a
- Data.GenericTrie.Internal: genericTrieNull :: (TrieRep k ~ TrieRepDefault k) => Trie k a -> Bool
+ Data.GenericTrie.Internal: genericTrieNull :: TrieRep k ~ TrieRepDefault k => Trie k a -> Bool
- Data.GenericTrie.Internal: trieEmpty :: (TrieKey k, (TrieRep k ~ TrieRepDefault k)) => Trie k a
+ Data.GenericTrie.Internal: trieEmpty :: (TrieKey k, TrieRep k ~ TrieRepDefault k) => Trie k a
- Data.GenericTrie.Internal: trieNull :: (TrieKey k, (TrieRep k ~ TrieRepDefault k)) => Trie k a -> Bool
+ Data.GenericTrie.Internal: trieNull :: (TrieKey k, TrieRep k ~ TrieRepDefault k) => Trie k a -> Bool
- Data.GenericTrie.Internal: trieShowsPrec :: (TrieKey k, Show a, GTrieKeyShow (Rep k), TrieRep k ~ TrieRepDefault k) => Int -> Trie k a -> ShowS
+ Data.GenericTrie.Internal: trieShowsPrec :: (ShowTrieKey k, Show a, GTrieKeyShow (Rep k), TrieRep k ~ TrieRepDefault k) => Int -> Trie k a -> ShowS

Files

CHANGELOG.md view
@@ -1,8 +1,21 @@+0.3.2+-----++* Add a `trieAlter` method, and use it to speed up `alter`, `insert` and+  `delete`.+* Make the `Show` instance user friendly.+* Add support for GHC versions up to 9.4.+* Fix builds on GHC 7.8, and with old `containers` versions.+* Stop pretending to support GHC 7.4 and 7.6. These have not actually worked in+  some time, and it is hard to test on them.+ 0.3.1 -----+ * Improved strictness * GHC 8.4 compatibility  0.3.0.2 -------+ * GHC 8 compatibility
+ app/Main.hs view
@@ -0,0 +1,4 @@+module Main where++main :: IO ()+main = putStr ""
generic-trie.cabal view
@@ -1,5 +1,5 @@ name:                generic-trie-version:             0.3.1+version:             0.3.2 synopsis:            A map, where the keys may be complex structured data. description:         This type implements maps where the keys are themselves                      complex structured data.  For example, the keys may be@@ -18,6 +18,17 @@ cabal-version:       >=1.10 homepage:            http://github.com/glguy/tries bug-reports:         http://github.com/glguy/tries/issues+tested-with:         GHC ==7.8.4+                      || ==7.10.3+                      || ==8.0.2+                      || ==8.2.2+                      || ==8.4.2+                      || ==8.6.1+                      || ==8.8.1+                      || ==8.10.7+                      || ==9.0.2+                      || ==9.2.2+                      || ==9.4.2  extra-source-files:   CHANGELOG.md@@ -25,13 +36,24 @@ library   exposed-modules:     Data.GenericTrie,                        Data.GenericTrie.Internal-  build-depends:       base             >= 4.5     && < 4.11,-                       transformers     >= 0.2     && < 0.6,-                       containers       >= 0.4.2.1 && < 0.6+  other-modules:       Prelude+  build-depends:       base             >= 4.7.0.2 && < 4.18,+                       transformers     >= 0.2     && < 0.7,+                       containers       >= 0.4.2.1 && < 0.7   GHC-options:         -O2 -Wall    hs-source-dirs:      src   default-language:    Haskell2010++-- cabal repl seems to choke on the custom prelude if you just+-- run it on the library in the usual way. If you instead say+-- cabal repl bogus, then it works just fine.+executable bogus+  main-is:             Main.hs+  hs-source-dirs:      app+  default-language:    Haskell2010+  build-depends:       base+                     , generic-trie  source-repository head   type: git
src/Data/GenericTrie.hs view
@@ -32,6 +32,7 @@   -- * Trie interface     Trie   , TrieKey+  , ShowTrieKey    -- ** Construction   , empty@@ -61,6 +62,7 @@    -- ** Traversing   , traverseWithKey+  , traverseMaybeWithKey   , mapMaybe   , mapMaybeWithKey   , filter@@ -81,7 +83,6 @@   , OrdKey(..)   ) where -import Control.Applicative (Applicative) import Data.List (foldl') import Data.Maybe (isNothing, isJust) import Prelude hiding (lookup, null, filter)@@ -152,6 +153,13 @@ mapMaybeWithKey = trieMapMaybeWithKey {-# INLINE mapMaybeWithKey #-} +-- | Perform an action for each value in a trie and keep the elements+-- of the trie that result in a 'Just' value.+traverseMaybeWithKey :: (TrieKey k, Applicative f)+                     => (k -> a -> f (Maybe b)) -> Trie k a -> f (Trie k b)+traverseMaybeWithKey = trieTraverseMaybeWithKey+{-# INLINE traverseMaybeWithKey #-}+ -- | Filter the values of a trie with the given predicate. filter :: TrieKey k => (a -> Bool) -> Trie k a -> Trie k a filter p = filterWithKey (const p)@@ -194,10 +202,8 @@ -- at the given key, if one exists, and should return a value to insert at -- that location, or 'Nothing' to delete from that location. alter :: TrieKey k => k -> (Maybe a -> Maybe a) -> Trie k a -> Trie k a-alter k f t =-  case f (lookup k t) of-    Just v' -> insert k v' t-    Nothing -> delete k t+alter = trieAlter+{-# INLINE alter #-}  -- | Insert a value at the given key. The combining function is used -- when a value is already stored at that key. The new value is the@@ -223,10 +229,6 @@ -- | Returns 'False' when the 'Trie' has a value stored at the given key. notMember :: TrieKey k => k -> Trie k a -> Bool notMember k t = isNothing (lookup k t)---- | Transform a trie to an association list.-toList :: TrieKey k => Trie k a -> [(k,a)]-toList = foldWithKey (\k v xs -> (k,v) : xs) []  -- | Left-biased union of two tries union :: TrieKey k => Trie k a -> Trie k a -> Trie k a
src/Data/GenericTrie/Internal.hs view
@@ -7,7 +7,10 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE Trustworthy #-} -- coerce {-# LANGUAGE CPP #-} -- MProxy on ghc >= 8-+{-# LANGUAGE EmptyCase #-}+#if __GLASGOW_HASKELL__ >= 810+{-# LANGUAGE StandaloneKindSignatures #-}+#endif #if MIN_VERSION_base(4,9,0) {-# LANGUAGE DataKinds #-} -- Meta #endif@@ -15,8 +18,10 @@ -- | Unstable implementation details module Data.GenericTrie.Internal   ( TrieKey(..)+  , ShowTrieKey(..)   , Trie(..)   , OrdKey(..)+  , toList   -- * Generic derivation implementation   , genericTrieNull   , genericTrieMap@@ -25,29 +30,38 @@   , genericInsert   , genericLookup   , genericDelete+  , genericAlter   , genericMapMaybeWithKey   , genericSingleton   , genericEmpty   , genericFoldWithKey   , genericTraverseWithKey+  , genericTraverseMaybeWithKey   , TrieRepDefault   , GTrieKey(..)   , GTrie(..)   ) where -import Control.Applicative (Applicative, liftA2) import Data.Char (chr, ord) import Data.Coerce (coerce)-import Data.Foldable (Foldable) import Data.IntMap (IntMap)+#if MIN_VERSION_base(4,9,0)+import Data.Kind (Type)+#endif import Data.Map (Map) import Data.Maybe (isNothing)-import Data.Traversable (Traversable,traverse) import GHC.Generics import qualified Data.Foldable as Foldable+import qualified Data.Traversable as Traversable import qualified Data.IntMap as IntMap import qualified Data.Map as Map import Prelude+#if MIN_VERSION_base(4,8,0)+import Data.Void (Void)+#endif+#if MIN_VERSION_base(4,8,0)+import Numeric.Natural+#endif  -- | Types that may be used as the key of a 'Trie'. --@@ -56,7 +70,11 @@ class TrieKey k where    -- | Type of the representation of tries for this key.+#if MIN_VERSION_base(4,9,0)+  type TrieRep k :: Type -> Type+#else   type TrieRep k :: * -> *+#endif    -- | Construct an empty trie   trieEmpty :: Trie k a@@ -73,6 +91,9 @@   -- | Delete element from trie   trieDelete :: k -> Trie k a -> Trie k a +  -- | Insert, modify, or remove an element in a trie+  trieAlter :: k -> (Maybe a -> Maybe a) -> Trie k a -> Trie k a+   -- | Construct a trie holding a single value   trieSingleton :: k -> a -> Trie k a @@ -82,9 +103,6 @@   -- | Traverse the values stored in a trie   trieTraverse :: Applicative f => (a -> f b) -> Trie k a -> f (Trie k b) -  -- | Show the representation of a trie-  trieShowsPrec :: Show a => Int -> Trie k a -> ShowS-   -- | Apply a function to the values of a 'Trie' and keep the elements   -- of the trie that result in a 'Just' value.   trieMapMaybeWithKey :: (k -> a -> Maybe b) -> Trie k a -> Trie k b@@ -95,6 +113,10 @@   -- | Traverse a trie with a function of both key and value.   trieTraverseWithKey :: Applicative f => (k -> a -> f b) -> Trie k a -> f (Trie k b) +  -- | Traverse a trie with a function of both key and value, and keep the elements+  -- of the trie that result in a 'Just' value.+  trieTraverseMaybeWithKey :: Applicative f => (k -> a -> f (Maybe b)) -> Trie k a -> f (Trie k b)+   trieMergeWithKey :: (k -> a -> b -> Maybe c) ->                       (Trie k a -> Trie k c) ->                       (Trie k b -> Trie k c) ->@@ -133,6 +155,11 @@     k -> Trie k a -> Trie k a   trieDelete = genericDelete +  default trieAlter ::+    ( GTrieKey (Rep k), Generic k , TrieRep k ~ TrieRepDefault k) =>+    k -> (Maybe a -> Maybe a) -> Trie k a -> Trie k a+  trieAlter = genericAlter+   default trieMap ::     ( GTrieKey (Rep k) , TrieRep k ~ TrieRepDefault k) =>     (a -> b) -> Trie k a -> Trie k b@@ -143,11 +170,6 @@     (a -> f b) -> Trie k a -> f (Trie k b)   trieTraverse = genericTrieTraverse -  default trieShowsPrec ::-    ( Show a, GTrieKeyShow (Rep k) , TrieRep k ~ TrieRepDefault k) =>-    Int -> Trie k a -> ShowS-  trieShowsPrec = genericTrieShowsPrec-   default trieMapMaybeWithKey ::     ( GTrieKey (Rep k) , Generic k, TrieRep k ~ TrieRepDefault k) =>     (k -> a -> Maybe b) -> Trie k a -> Trie k b@@ -163,6 +185,11 @@     (k -> a -> f b) -> Trie k a -> f (Trie k b)   trieTraverseWithKey = genericTraverseWithKey +  default trieTraverseMaybeWithKey ::+    ( GTrieKey (Rep k) , TrieRep k ~ TrieRepDefault k, Generic k, Applicative f) =>+    (k -> a -> f (Maybe b)) -> Trie k a -> f (Trie k b)+  trieTraverseMaybeWithKey = genericTraverseMaybeWithKey+   default trieMergeWithKey ::     ( GTrieKey (Rep k) , TrieRep k ~ TrieRepDefault k, Generic k ) =>     (k -> a -> b -> Maybe c) ->@@ -174,7 +201,19 @@ -- | A map from keys of type @k@, to values of type @a@. newtype Trie k a = MkTrie (TrieRep k a) +-- | Transform a trie to an association list.+toList :: TrieKey k => Trie k a -> [(k,a)]+toList = trieFoldWithKey (\k v xs -> (k,v) : xs) [] +class TrieKey k => ShowTrieKey k where+  -- | Show a representation of the internal structure of a trie+  trieShowsPrec :: Show a => Int -> Trie k a -> ShowS+  default trieShowsPrec ::+    ( Show a, GTrieKeyShow (Rep k) , TrieRep k ~ TrieRepDefault k) =>+    Int -> Trie k a -> ShowS+  trieShowsPrec = genericTrieShowsPrec++ ------------------------------------------------------------------------------ -- Manually derived instances for base types ------------------------------------------------------------------------------@@ -185,13 +224,19 @@   trieLookup k (MkTrie x)       = IntMap.lookup k x   trieInsert k v (MkTrie t)     = MkTrie (IntMap.insert k v t)   trieDelete k (MkTrie t)       = MkTrie (IntMap.delete k t)+  trieAlter k f (MkTrie t)      = MkTrie (IntMap.alter f k t)   trieEmpty                     = MkTrie IntMap.empty   trieSingleton k v             = MkTrie (IntMap.singleton k v)   trieNull (MkTrie x)           = IntMap.null x   trieMap f (MkTrie x)          = MkTrie (IntMap.map f x)   trieTraverse f (MkTrie x)     = fmap MkTrie (traverse f x)-  trieShowsPrec p (MkTrie x)    = showsPrec p x   trieMapMaybeWithKey f (MkTrie x)  = MkTrie (IntMap.mapMaybeWithKey f x)+  trieTraverseMaybeWithKey f (MkTrie x) =+#if MIN_VERSION_containers (0,6,4)+    MkTrie <$> IntMap.traverseMaybeWithKey f x+#else+    MkTrie . IntMap.mapMaybe id <$> IntMap.traverseWithKey f x+#endif   trieFoldWithKey f z (MkTrie x)    = IntMap.foldrWithKey f z x   trieTraverseWithKey f (MkTrie x)  = fmap MkTrie (IntMap.traverseWithKey f x)   trieMergeWithKey f g h (MkTrie x) (MkTrie y) = MkTrie (IntMap.mergeWithKey f (coerce g) (coerce h) x y)@@ -199,29 +244,82 @@   {-# INLINABLE trieInsert #-}   {-# INLINABLE trieLookup #-}   {-# INLINABLE trieDelete #-}+  {-# INLINABLE trieAlter #-}   {-# INLINABLE trieSingleton #-}   {-# INLINABLE trieFoldWithKey #-}-  {-# INLINABLE trieShowsPrec #-}   {-# INLINABLE trieTraverse #-}   {-# INLINABLE trieTraverseWithKey #-}   {-# INLINABLE trieNull #-}   {-# INLINABLE trieMap #-}   {-# INLINABLE trieMergeWithKey #-}   {-# INLINABLE trieMapMaybeWithKey #-}+  {-# INLINABLE trieTraverseMaybeWithKey #-} +instance ShowTrieKey Int where+  trieShowsPrec p (MkTrie x)    = showsPrec p x+  {-# INLINABLE trieShowsPrec #-}+ -- | 'Integer' tries are implemented with 'Map'. instance TrieKey Integer where   type TrieRep Integer              = Map Integer   trieLookup k (MkTrie t)           = Map.lookup k t   trieInsert k v (MkTrie t)         = MkTrie (Map.insert k v t)   trieDelete k (MkTrie t)           = MkTrie (Map.delete k t)+  trieAlter k f (MkTrie t)          = MkTrie (Map.alter f k t)   trieEmpty                         = MkTrie Map.empty   trieSingleton k v                 = MkTrie (Map.singleton k v)   trieNull (MkTrie x)               = Map.null x   trieMap f (MkTrie x)              = MkTrie (Map.map f x)   trieTraverse f (MkTrie x)         = fmap MkTrie (traverse f x)+  trieMapMaybeWithKey f (MkTrie x)  = MkTrie (Map.mapMaybeWithKey f x)+  trieTraverseMaybeWithKey f (MkTrie x) =+#if MIN_VERSION_containers (0,5,8)+    MkTrie <$> Map.traverseMaybeWithKey f x+#else+    MkTrie . Map.mapMaybe id <$> Map.traverseWithKey f x+#endif+  trieFoldWithKey f z (MkTrie x)    = Map.foldrWithKey f z x+  trieTraverseWithKey f (MkTrie x)  = fmap MkTrie (Map.traverseWithKey f x)+  trieMergeWithKey f g h (MkTrie x) (MkTrie y) = MkTrie (Map.mergeWithKey f (coerce g) (coerce h) x y)+  {-# INLINABLE trieEmpty #-}+  {-# INLINABLE trieInsert #-}+  {-# INLINABLE trieLookup #-}+  {-# INLINABLE trieDelete #-}+  {-# INLINABLE trieAlter #-}+  {-# INLINABLE trieSingleton #-}+  {-# INLINABLE trieFoldWithKey #-}+  {-# INLINABLE trieTraverse #-}+  {-# INLINABLE trieTraverseWithKey #-}+  {-# INLINABLE trieTraverseMaybeWithKey #-}+  {-# INLINABLE trieNull #-}+  {-# INLINABLE trieMap #-}+  {-# INLINABLE trieMergeWithKey #-}+  {-# INLINABLE trieMapMaybeWithKey #-}++instance ShowTrieKey Integer where   trieShowsPrec p (MkTrie x)        = showsPrec p x+  {-# INLINABLE trieShowsPrec #-}++#if MIN_VERSION_base(4,8,0)+-- | 'Natural' tries are implemented with 'Map'.+instance TrieKey Natural where+  type TrieRep Natural              = Map Natural+  trieLookup k (MkTrie t)           = Map.lookup k t+  trieInsert k v (MkTrie t)         = MkTrie (Map.insert k v t)+  trieDelete k (MkTrie t)           = MkTrie (Map.delete k t)+  trieAlter k f (MkTrie t)          = MkTrie (Map.alter f k t)+  trieEmpty                         = MkTrie Map.empty+  trieSingleton k v                 = MkTrie (Map.singleton k v)+  trieNull (MkTrie x)               = Map.null x+  trieMap f (MkTrie x)              = MkTrie (Map.map f x)+  trieTraverse f (MkTrie x)         = fmap MkTrie (traverse f x)   trieMapMaybeWithKey f (MkTrie x)  = MkTrie (Map.mapMaybeWithKey f x)+  trieTraverseMaybeWithKey f (MkTrie x) =+#if MIN_VERSION_containers (0,5,8)+    MkTrie <$> Map.traverseMaybeWithKey f x+#else+    MkTrie . Map.mapMaybe id <$> Map.traverseWithKey f x+#endif   trieFoldWithKey f z (MkTrie x)    = Map.foldrWithKey f z x   trieTraverseWithKey f (MkTrie x)  = fmap MkTrie (Map.traverseWithKey f x)   trieMergeWithKey f g h (MkTrie x) (MkTrie y) = MkTrie (Map.mergeWithKey f (coerce g) (coerce h) x y)@@ -229,29 +327,83 @@   {-# INLINABLE trieInsert #-}   {-# INLINABLE trieLookup #-}   {-# INLINABLE trieDelete #-}+  {-# INLINABLE trieAlter #-}   {-# INLINABLE trieSingleton #-}   {-# INLINABLE trieFoldWithKey #-}+  {-# INLINABLE trieTraverse #-}+  {-# INLINABLE trieTraverseWithKey #-}+  {-# INLINABLE trieTraverseMaybeWithKey #-}+  {-# INLINABLE trieNull #-}+  {-# INLINABLE trieMap #-}+  {-# INLINABLE trieMergeWithKey #-}+  {-# INLINABLE trieMapMaybeWithKey #-}++instance ShowTrieKey Natural where+  trieShowsPrec p (MkTrie x)        = showsPrec p x   {-# INLINABLE trieShowsPrec #-}+#endif++-- | 'Word' tries are implemented with 'IntMap'.+instance TrieKey Word where+  type TrieRep Word                 = IntMap+  trieLookup k (MkTrie t)           = IntMap.lookup (fromIntegral k) t+  trieDelete k (MkTrie t)           = MkTrie (IntMap.delete (fromIntegral k) t)+  trieInsert k v (MkTrie t)         = MkTrie (IntMap.insert (fromIntegral k) v t)+  trieAlter k f (MkTrie t)          = MkTrie (IntMap.alter f (fromIntegral k) t)+  trieEmpty                         = MkTrie IntMap.empty+  trieSingleton k v                 = MkTrie (IntMap.singleton (fromIntegral k) v)+  trieNull (MkTrie x)               = IntMap.null x+  trieMap f (MkTrie x)              = MkTrie (IntMap.map f x)+  trieTraverse f (MkTrie x)         = fmap MkTrie (traverse f x)+  trieMapMaybeWithKey f (MkTrie x)  = MkTrie (IntMap.mapMaybeWithKey (f . fromIntegral) x)+  trieTraverseMaybeWithKey f (MkTrie x) =+#if MIN_VERSION_containers (0,6,4)+    MkTrie <$> IntMap.traverseMaybeWithKey (f . fromIntegral) x+#else+    MkTrie . IntMap.mapMaybe id <$> IntMap.traverseWithKey (f . fromIntegral) x+#endif+  trieFoldWithKey f z (MkTrie x)    = IntMap.foldrWithKey (f . fromIntegral) z x+  trieTraverseWithKey f (MkTrie x)  = fmap MkTrie (IntMap.traverseWithKey (f . fromIntegral) x)+  trieMergeWithKey f g h (MkTrie x) (MkTrie y) = MkTrie (IntMap.mergeWithKey (f . fromIntegral) (coerce g) (coerce h) x y)+  {-# INLINABLE trieEmpty #-}+  {-# INLINABLE trieInsert #-}+  {-# INLINABLE trieLookup #-}+  {-# INLINABLE trieDelete #-}+  {-# INLINABLE trieAlter #-}+  {-# INLINABLE trieSingleton #-}+  {-# INLINABLE trieFoldWithKey #-}   {-# INLINABLE trieTraverse #-}   {-# INLINABLE trieTraverseWithKey #-}+  {-# INLINABLE trieTraverseMaybeWithKey #-}   {-# INLINABLE trieNull #-}   {-# INLINABLE trieMap #-}   {-# INLINABLE trieMergeWithKey #-}   {-# INLINABLE trieMapMaybeWithKey #-} +instance ShowTrieKey Word where+  trieShowsPrec p (MkTrie x) =+    showParen (p > 10) (showString "fromList " . shows [(fromIntegral k :: Word, v) | (k,v) <- IntMap.toList x])+  {-# INLINABLE trieShowsPrec #-}+ -- | 'Char' tries are implemented with 'IntMap'. instance TrieKey Char where   type TrieRep Char                 = IntMap   trieLookup k (MkTrie t)           = IntMap.lookup (ord k) t   trieDelete k (MkTrie t)           = MkTrie (IntMap.delete (ord k) t)   trieInsert k v (MkTrie t)         = MkTrie (IntMap.insert (ord k) v t)+  trieAlter k f (MkTrie t)          = MkTrie (IntMap.alter f (ord k) t)   trieEmpty                         = MkTrie IntMap.empty   trieSingleton k v                 = MkTrie (IntMap.singleton (ord k) v)   trieNull (MkTrie x)               = IntMap.null x   trieMap f (MkTrie x)              = MkTrie (IntMap.map f x)   trieTraverse f (MkTrie x)         = fmap MkTrie (traverse f x)-  trieShowsPrec p (MkTrie x)        = showsPrec p x   trieMapMaybeWithKey f (MkTrie x)  = MkTrie (IntMap.mapMaybeWithKey (f . chr) x)+  trieTraverseMaybeWithKey f (MkTrie x) =+#if MIN_VERSION_containers (0,6,4)+    MkTrie <$> IntMap.traverseMaybeWithKey (f . chr) x+#else+    MkTrie . IntMap.mapMaybe id <$> IntMap.traverseWithKey (f . chr) x+#endif   trieFoldWithKey f z (MkTrie x)    = IntMap.foldrWithKey (f . chr) z x   trieTraverseWithKey f (MkTrie x)  = fmap MkTrie (IntMap.traverseWithKey (f . chr) x)   trieMergeWithKey f g h (MkTrie x) (MkTrie y) = MkTrie (IntMap.mergeWithKey (f . chr) (coerce g) (coerce h) x y)@@ -259,16 +411,21 @@   {-# INLINABLE trieInsert #-}   {-# INLINABLE trieLookup #-}   {-# INLINABLE trieDelete #-}+  {-# INLINABLE trieAlter #-}   {-# INLINABLE trieSingleton #-}   {-# INLINABLE trieFoldWithKey #-}-  {-# INLINABLE trieShowsPrec #-}   {-# INLINABLE trieTraverse #-}   {-# INLINABLE trieTraverseWithKey #-}+  {-# INLINABLE trieTraverseMaybeWithKey #-}   {-# INLINABLE trieNull #-}   {-# INLINABLE trieMap #-}   {-# INLINABLE trieMergeWithKey #-}   {-# INLINABLE trieMapMaybeWithKey #-} +instance ShowTrieKey Char where+  trieShowsPrec p (MkTrie x)        = showsPrec p x+  {-# INLINABLE trieShowsPrec #-}+ -- | Tries indexed by 'OrdKey' will be represented as an ordinary 'Map' -- and the keys will be compared based on the 'Ord' instance for @k@. newtype OrdKey k = OrdKey { getOrdKey :: k }@@ -278,18 +435,24 @@ -- intended for cases where it is better for some reason -- to force the use of a 'Map' than to use the generically -- derived structure.-instance (Show k, Ord k) => TrieKey (OrdKey k) where+instance Ord k => TrieKey (OrdKey k) where   type TrieRep (OrdKey k)               = Map k   trieLookup (OrdKey k) (MkTrie x)      = Map.lookup k x   trieInsert (OrdKey k) v (MkTrie x)    = MkTrie (Map.insert k v x)   trieDelete (OrdKey k) (MkTrie x)      = MkTrie (Map.delete k x)+  trieAlter (OrdKey k) f (MkTrie x)     = MkTrie (Map.alter f k x)   trieEmpty                             = MkTrie Map.empty   trieSingleton (OrdKey k) v            = MkTrie (Map.singleton k v)   trieNull (MkTrie x)                   = Map.null x   trieMap f (MkTrie x)                  = MkTrie (Map.map f x)   trieTraverse f (MkTrie x)             = fmap MkTrie (traverse f x)-  trieShowsPrec p (MkTrie x)            = showsPrec p x   trieMapMaybeWithKey f (MkTrie x)      = MkTrie (Map.mapMaybeWithKey (f . OrdKey) x)+  trieTraverseMaybeWithKey f (MkTrie x) =+#if MIN_VERSION_containers (0,5,8)+    MkTrie <$> Map.traverseMaybeWithKey (f . OrdKey) x+#else+    MkTrie . Map.mapMaybe id <$> Map.traverseWithKey (f . OrdKey) x+#endif   trieFoldWithKey f z (MkTrie x)        = Map.foldrWithKey (f . OrdKey) z x   trieTraverseWithKey f (MkTrie x)      = fmap MkTrie (Map.traverseWithKey (f . OrdKey) x)   trieMergeWithKey f g h (MkTrie x) (MkTrie y) = MkTrie (Map.mergeWithKey (f . OrdKey) (coerce g) (coerce h) x y)@@ -297,29 +460,49 @@   {-# INLINABLE trieInsert #-}   {-# INLINABLE trieLookup #-}   {-# INLINABLE trieDelete #-}+  {-# INLINABLE trieAlter #-}   {-# INLINABLE trieSingleton #-}   {-# INLINABLE trieFoldWithKey #-}-  {-# INLINABLE trieShowsPrec #-}   {-# INLINABLE trieTraverse #-}   {-# INLINABLE trieTraverseWithKey #-}+  {-# INLINABLE trieTraverseMaybeWithKey #-}   {-# INLINABLE trieNull #-}   {-# INLINABLE trieMap #-}   {-# INLINABLE trieMergeWithKey #-}   {-# INLINABLE trieMapMaybeWithKey #-} +instance (Show k, Ord k) => ShowTrieKey (OrdKey k) where+  trieShowsPrec p (MkTrie x)            = showsPrec p x+  {-# INLINABLE trieShowsPrec #-}+ ------------------------------------------------------------------------------ -- Automatically derived instances for common types ------------------------------------------------------------------------------ +#if MIN_VERSION_base(4,8,0)+instance                                      TrieKey Void+instance                                      ShowTrieKey Void+#endif instance                                      TrieKey ()+instance                                      ShowTrieKey () instance                                      TrieKey Bool+instance                                      ShowTrieKey Bool+instance                                      TrieKey Ordering+instance                                      ShowTrieKey Ordering instance TrieKey k                         => TrieKey (Maybe k)+instance ShowTrieKey k                     => ShowTrieKey (Maybe k) instance (TrieKey a, TrieKey b)            => TrieKey (Either a b)+instance (ShowTrieKey a, ShowTrieKey b)    => ShowTrieKey (Either a b) instance (TrieKey a, TrieKey b)            => TrieKey (a,b)+instance (ShowTrieKey a, ShowTrieKey b)    => ShowTrieKey (a,b) instance (TrieKey a, TrieKey b, TrieKey c) => TrieKey (a,b,c)+instance (ShowTrieKey a, ShowTrieKey b, ShowTrieKey c) => ShowTrieKey (a,b,c) instance (TrieKey a, TrieKey b, TrieKey c, TrieKey d) => TrieKey (a,b,c,d)+instance (ShowTrieKey a, ShowTrieKey b, ShowTrieKey c, ShowTrieKey d) => ShowTrieKey (a,b,c,d) instance (TrieKey a, TrieKey b, TrieKey c, TrieKey d, TrieKey e) => TrieKey (a,b,c,d,e)+instance (ShowTrieKey a, ShowTrieKey b, ShowTrieKey c, ShowTrieKey d, ShowTrieKey e) => ShowTrieKey (a,b,c,d,e) instance TrieKey k                         => TrieKey [k]+instance ShowTrieKey k                     => ShowTrieKey [k]  ------------------------------------------------------------------------------ -- Generic 'TrieKey' method implementations@@ -380,6 +563,15 @@ genericDelete k m = wrap (gtrieDelete (from k) =<< unwrap m) {-# INLINABLE genericDelete #-} +-- | Generic implementation of 'alter'. This is the default implementation.+genericAlter ::+    ( GTrieKey (Rep k), Generic k+    , TrieRep k ~ TrieRepDefault k+    ) =>+    k -> (Maybe a -> Maybe a) -> Trie k a -> Trie k a+genericAlter k f m = wrap (gtrieAlter (from k) f =<< unwrap m)+{-# INLINABLE genericAlter #-}+ -- | Generic implementation of 'trieMap'. This is the default implementation. genericTrieMap ::     ( GTrieKey (Rep k)@@ -444,6 +636,16 @@ genericTraverseWithKey f m = fmap wrap (traverse (gtraverseWithKey (f . to)) (unwrap m)) {-# INLINABLE genericTraverseWithKey #-} +-- | Generic implementation of 'traverseMaybeWithKey'. This is the default implementation.+genericTraverseMaybeWithKey ::+    ( GTrieKey (Rep k), Generic k+    , TrieRep k ~ TrieRepDefault k+    , Applicative f+    ) =>+    (k -> a -> f (Maybe b)) -> Trie k a -> f (Trie k b)+genericTraverseMaybeWithKey f m = fmap (maybe (MkTrie EmptyTrie) wrap) (traverse (gtraverseMaybeWithKey (f . to)) (unwrap m))+{-# INLINABLE genericTraverseMaybeWithKey #-}+ -- | Generic implementation of 'mergeWithKey'. This is the default implementation. genericMergeWithKey ::     ( GTrieKey (Rep k), Generic k@@ -481,7 +683,15 @@ data TrieRepDefault k a = EmptyTrie | NonEmptyTrie !(GTrie (Rep k) a)  -- | Mapping of generic representation of keys to trie structures.+#if __GLASGOW_HASKELL__ >= 810+type GTrie :: (Type -> Type) -> Type -> Type+data    family   GTrie f a+#elif MIN_VERSION_base(4,9,0)+data    family   GTrie (f :: Type -> Type) a+#else data    family   GTrie (f :: * -> *) a+#endif+ newtype instance GTrie (M1 i c f) a     = MTrie (GTrie f a) data    instance GTrie (f :+: g)  a     = STrieL !(GTrie f a)                                         | STrieR !(GTrie g a)@@ -501,11 +711,13 @@   gtrieInsert    :: f p -> a -> GTrie f a -> GTrie f a   gtrieSingleton :: f p -> a -> GTrie f a   gtrieDelete    :: f p -> GTrie f a -> Maybe (GTrie f a)+  gtrieAlter     :: f p -> (Maybe a -> Maybe a) -> GTrie f a -> Maybe (GTrie f a)   gtrieMap       :: (a -> b) -> GTrie f a -> GTrie f b   gtrieTraverse  :: Applicative m => (a -> m b) -> GTrie f a -> m (GTrie f b)   gmapMaybeWithKey :: (f p -> a -> Maybe b) -> GTrie f a -> Maybe (GTrie f b)   gfoldWithKey   :: (f p -> a -> r -> r) -> r -> GTrie f a -> r   gtraverseWithKey :: Applicative m => (f p -> a -> m b) -> GTrie f a -> m (GTrie f b)+  gtraverseMaybeWithKey :: Applicative m => (f p -> a -> m (Maybe b)) -> GTrie f a -> m (Maybe (GTrie f b))   gmergeWithKey  :: (f p -> a -> b -> Maybe c) ->                     (GTrie f a -> Maybe (GTrie f c)) ->                     (GTrie f b -> Maybe (GTrie f c)) ->@@ -527,24 +739,28 @@   gtrieInsert (M1 k) v (MTrie t)= MTrie (gtrieInsert k v t)   gtrieSingleton (M1 k) v       = MTrie (gtrieSingleton k v)   gtrieDelete (M1 k) (MTrie x)  = fmap MTrie (gtrieDelete k x)+  gtrieAlter (M1 k) f (MTrie x) = fmap MTrie (gtrieAlter k f x)   gtrieMap f (MTrie x)          = MTrie (gtrieMap f x)   gtrieTraverse f (MTrie x)     = fmap MTrie (gtrieTraverse f x)   gmapMaybeWithKey f (MTrie x)  = fmap MTrie (gmapMaybeWithKey (f . M1) x)   gfoldWithKey f z (MTrie x)    = gfoldWithKey (f . M1) z x   gtraverseWithKey f (MTrie x)  = fmap MTrie (gtraverseWithKey (f . M1) x)+  gtraverseMaybeWithKey f (MTrie x)  = fmap coerce (gtraverseMaybeWithKey (f . M1) x)   gmergeWithKey f g h (MTrie x) (MTrie y) = fmap MTrie (gmergeWithKey (f . M1) (coerce g) (coerce h) x y)   {-# INLINE gtrieLookup #-}   {-# INLINE gtrieInsert #-}   {-# INLINE gtrieSingleton #-}   {-# INLINE gtrieDelete #-}+  {-# INLINE gtrieAlter #-}   {-# INLINE gtrieMap #-}   {-# INLINE gmapMaybeWithKey #-}   {-# INLINE gtrieTraverse #-}   {-# INLINE gfoldWithKey #-}   {-# INLINE gtraverseWithKey #-}+  {-# INLINE gtraverseMaybeWithKey #-}  #if MIN_VERSION_base(4,9,0)-data MProxy (c :: Meta) (f :: * -> *) a = MProxy+data MProxy (c :: Meta) (f :: Type -> Type) a = MProxy #else data MProxy (c :: *)    (f :: * -> *) a = MProxy #endif@@ -575,11 +791,13 @@   gtrieInsert (K1 k) v (KTrie t)        = KTrie (trieInsert k v t)   gtrieSingleton (K1 k) v               = KTrie (trieSingleton k v)   gtrieDelete (K1 k) (KTrie t)          = fmap KTrie (checkNull (trieDelete k t))+  gtrieAlter (K1 k) f (KTrie t)         = fmap KTrie (checkNull (trieAlter k f t))   gtrieMap f (KTrie x)                  = KTrie (trieMap f x)   gtrieTraverse f (KTrie x)             = fmap KTrie (trieTraverse f x)   gmapMaybeWithKey f (KTrie x)          = fmap KTrie (checkNull (trieMapMaybeWithKey (f . K1) x))   gfoldWithKey f z (KTrie x)            = trieFoldWithKey (f . K1) z x   gtraverseWithKey f (KTrie x)          = fmap KTrie (trieTraverseWithKey (f . K1) x)+  gtraverseMaybeWithKey f (KTrie x)     = fmap (fmap KTrie . checkNull) (trieTraverseMaybeWithKey (f . K1) x)   gmergeWithKey f g h (KTrie x) (KTrie y) = fmap KTrie (checkNull (trieMergeWithKey (f . K1) g' h' x y))      where      g' t = case g (KTrie t) of@@ -592,15 +810,17 @@   {-# INLINE gtrieInsert #-}   {-# INLINE gtrieSingleton #-}   {-# INLINE gtrieDelete #-}+  {-# INLINE gtrieAlter #-}   {-# INLINE gtrieMap #-}   {-# INLINE gtrieTraverse #-}   {-# INLINE gfoldWithKey #-}   {-# INLINE gtraverseWithKey #-}+  {-# INLINE gtraverseMaybeWithKey #-}   {-# INLINE gmergeWithKey #-}   {-# INLINE gmapMaybeWithKey #-} -instance TrieKey k => GTrieKeyShow (K1 i k) where-  gtrieShowsPrec p (KTrie x)            = showsPrec p x+instance ShowTrieKey k => GTrieKeyShow (K1 i k) where+  gtrieShowsPrec p (KTrie x)            = trieShowsPrec p x  ------------------------------------------------------------------------------ -- Generic implementation for products@@ -610,14 +830,35 @@ instance (GTrieKey f, GTrieKey g) => GTrieKey (f :*: g) where    gtrieLookup (i :*: j) (PTrie x)       = gtrieLookup j =<< gtrieLookup i x-  gtrieInsert (i :*: j) v (PTrie t)     = case gtrieLookup i t of-                                            Nothing -> PTrie (gtrieInsert i (gtrieSingleton j v) t)-                                            Just ti -> PTrie (gtrieInsert i (gtrieInsert j v ti) t)-  gtrieDelete (i :*: j) (PTrie t)       = case gtrieLookup i t of-                                            Nothing -> Just (PTrie t)-                                            Just ti -> case gtrieDelete j ti of-                                                         Nothing -> fmap PTrie $! gtrieDelete i t-                                                         Just tj -> Just $! PTrie (gtrieInsert i tj t)+  gtrieInsert (i :*: j) v (PTrie t)     = case gtrieAlter i f t of+  -- The "impossible" error is unfortunate. We *could* add another function+  --+  --   ginsertChange :: f i -> (Maybe a -> a) -> GTrie i a -> GTrie i a+  --+  -- and use that, but that would only push the "impossible" errors to the+  -- implementations using `Map` and `IntMap`, which doesn't seem to help.+                                            Nothing -> error "gtrieInsert: insertion produced an empty trie"+                                            Just t' -> PTrie t'+    where+      -- f :: Maybe (GTrie g a) -> Maybe (GTrie g a)+      f Nothing = Just $! gtrieSingleton j v+      f (Just u) = Just $! gtrieInsert j v u++  gtrieDelete (i :*: j) (PTrie t)       = fmap PTrie (gtrieAlter i f t)+    where+      -- f :: Maybe (GTrie g a) -> Maybe (GTrie g a)+      f Nothing = Nothing+      f (Just u) = gtrieDelete j u++  gtrieAlter (i :*: j) f (PTrie t)      = fmap PTrie (gtrieAlter i g t)+    where+      -- g :: Maybe (GTrie g a) -> Maybe (GTrie g a)+      g Nothing =+        case f Nothing of+          Nothing -> Nothing+          Just v -> Just $! gtrieSingleton j v+      g (Just u) = gtrieAlter j f u+   gtrieSingleton (i :*: j) v            = PTrie (gtrieSingleton i (gtrieSingleton j v))   gtrieMap f (PTrie x)                  = PTrie (gtrieMap (gtrieMap f) x)   gtrieTraverse f (PTrie x)             = fmap PTrie (gtrieTraverse (gtrieTraverse f) x)@@ -625,6 +866,8 @@   gfoldWithKey f z (PTrie x)            = gfoldWithKey (\i m r -> gfoldWithKey (\j -> f (i:*:j)) r m) z x   gtraverseWithKey f (PTrie x)          = fmap PTrie (gtraverseWithKey (\i ->                                                       gtraverseWithKey (\j -> f (i :*: j))) x)+  gtraverseMaybeWithKey f (PTrie x)     = fmap (fmap PTrie) (gtraverseMaybeWithKey (\i ->+                                                      gtraverseMaybeWithKey (\j -> f (i :*: j))) x)   gmergeWithKey f g h (PTrie x) (PTrie y) =     fmap PTrie $!        gmergeWithKey@@ -646,11 +889,13 @@   {-# INLINE gtrieLookup #-}   {-# INLINE gtrieInsert #-}   {-# INLINE gtrieDelete #-}+  {-# INLINE gtrieAlter #-}   {-# INLINE gtrieSingleton #-}   {-# INLINE gtrieMap #-}   {-# INLINE gtrieTraverse #-}   {-# INLINE gfoldWithKey #-}   {-# INLINE gtraverseWithKey #-}+  {-# INLINE gtraverseMaybeWithKey #-}   {-# INLINE gmergeWithKey #-}   {-# INLINE gmapMaybeWithKey #-} @@ -692,6 +937,25 @@                                             Nothing -> Just $! STrieL x                                             Just y' -> Just $! STrieB x y' +  gtrieAlter (L1 k) f (STrieL x)        = do+                                            x' <- gtrieAlter k f x+                                            Just $! STrieL x'+  gtrieAlter (L1 k) f t@(STrieR y)      = case f Nothing of+                                            Nothing -> Just t+                                            Just v -> Just $! STrieB (gtrieSingleton k v) y+  gtrieAlter (L1 k) f (STrieB x y)      = case gtrieAlter k f x of+                                            Just x' -> Just $! STrieB x' y+                                            Nothing -> Just $! STrieR y+  gtrieAlter (R1 k) f (STrieR y)        = do+                                            y' <- gtrieAlter k f y+                                            Just $! STrieR y'+  gtrieAlter (R1 k) f t@(STrieL x)      = case f Nothing of+                                            Nothing -> Just t+                                            Just v -> Just $! STrieB x (gtrieSingleton k v)+  gtrieAlter (R1 k) f (STrieB x y)      = case gtrieAlter k f y of+                                            Just y' -> Just $! STrieB x y'+                                            Nothing -> Just $! STrieL x+   gtrieMap f (STrieB x y)               = STrieB (gtrieMap f x) (gtrieMap f y)   gtrieMap f (STrieL x)                 = STrieL (gtrieMap f x)   gtrieMap f (STrieR y)                 = STrieR (gtrieMap f y)@@ -708,6 +972,16 @@                                             (Nothing, Just y') -> Just $! STrieR y'                                             (Just x', Just y') -> Just $! STrieB x' y' +  gtraverseMaybeWithKey f (STrieL x)         = fmap STrieL <$> gtraverseMaybeWithKey (f . L1) x+  gtraverseMaybeWithKey f (STrieR y)         = fmap STrieR <$> gtraverseMaybeWithKey (f . R1) y+  gtraverseMaybeWithKey f (STrieB x y)       =+    liftA2 finish (gtraverseMaybeWithKey (f . L1) x) (gtraverseMaybeWithKey (f . R1) y)+    where+      finish Nothing   Nothing    = Nothing+      finish (Just x') Nothing    = Just $! STrieL x'+      finish Nothing   (Just y')  = Just $! STrieR y'+      finish (Just x') (Just y')  = Just $! STrieB x' y'+   gfoldWithKey f z (STrieL x)           = gfoldWithKey (f . L1) z x   gfoldWithKey f z (STrieR y)           = gfoldWithKey (f . R1) z y   gfoldWithKey f z (STrieB x y)         = gfoldWithKey (f . L1) (gfoldWithKey (f . R1) z y) x@@ -752,11 +1026,13 @@   {-# INLINE gtrieLookup #-}   {-# INLINE gtrieInsert #-}   {-# INLINE gtrieDelete #-}+  {-# INLINE gtrieAlter #-}   {-# INLINE gtrieSingleton #-}   {-# INLINE gtrieTraverse #-}   {-# INLINE gtrieMap #-}   {-# INLINE gfoldWithKey #-}   {-# INLINE gtraverseWithKey #-}+  {-# INLINE gtraverseMaybeWithKey #-}   {-# INLINE gmergeWithKey #-}   {-# INLINE gmapMaybeWithKey #-} @@ -782,21 +1058,27 @@   gtrieLookup _ (UTrie x)       = Just x   gtrieInsert _ v _             = UTrie v   gtrieDelete _ _               = Nothing+  gtrieAlter _ f (UTrie x)      = case f (Just x) of+                                    Nothing -> Nothing+                                    Just x' -> Just $! UTrie x'   gtrieSingleton _              = UTrie   gtrieMap f (UTrie x)          = UTrie (f x)   gtrieTraverse f (UTrie x)     = fmap UTrie (f x)   gmapMaybeWithKey f (UTrie x)  = fmap UTrie $! f U1 x+  gtraverseMaybeWithKey f (UTrie x)  = fmap (fmap UTrie) $! f U1 x   gfoldWithKey f z (UTrie x)    = f U1 x z   gtraverseWithKey f (UTrie x)  = fmap UTrie (f U1 x)   gmergeWithKey f _ _ (UTrie x) (UTrie y) = fmap UTrie $! f U1 x y   {-# INLINE gtrieLookup #-}   {-# INLINE gtrieInsert #-}   {-# INLINE gtrieDelete #-}+  {-# INLINE gtrieAlter #-}   {-# INLINE gtrieSingleton #-}   {-# INLINE gtrieTraverse #-}   {-# INLINE gtrieMap #-}   {-# INLINE gfoldWithKey #-}   {-# INLINE gtraverseWithKey #-}+  {-# INLINE gtraverseMaybeWithKey #-}   {-# INLINE gmergeWithKey #-}   {-# INLINE gmapMaybeWithKey #-} @@ -807,26 +1089,43 @@ -- Generic implementation for empty types ------------------------------------------------------------------------------ --- | Tries of types without constructors are represented by a unit.+-- | Tries of types without constructors are represented by an empty type. instance GTrieKey V1 where-  gtrieLookup k t               = k `seq` t `seq` error "GTrieKey.V1: gtrieLookup"-  gtrieInsert k _ t             = k `seq` t `seq` error "GTrieKey.V1: gtrieInsert"-  gtrieDelete k t               = k `seq` t `seq` error "GTrieKey.V1: gtrieDelete"-  gtrieSingleton k _            = k `seq` error "GTrieKey.V1: gtrieSingleton"-  gtrieMap _ t                  = t `seq` error "GTrieKey.V1: gtrieMap"-  gtrieTraverse _ t             = t `seq` error "GTrieKey.V1: gtrieTraverse"-  gmapMaybeWithKey _ t          = t `seq` error "GTrieKey.V1: gmapMaybeWithKey"-  gfoldWithKey _ _ t            = t `seq` error "GTrieKey.V1: gmapFoldWithKey"-  gtraverseWithKey _ t          = t `seq` error "GTrieKey.V1: gtraverseWithKey"-  gmergeWithKey _ _ _ t u       = t `seq` u `seq` error "GTrieKey.V1: gmergeWithKey"+-- Why is this represented by an empty type? One might expect it would+-- be represented by a unit type, as there is exactly one total function+-- from any empty type to any other type. First, remember that+-- TrieRepDefault offers an EmptyTrie constructor. So a TrieMap Void x+-- will be represented by that. Next, note that while the generic Rep+-- types can be put together in arbitrary ways, derived Generic instances (which+-- are the only ones that matter) are always structured as sums of products,+-- and only use V1 at the outermost level. That is, V1 will only appear in a+-- generic representation if it is the only thing there (aside from M1+-- wrappers). In particular, the only GTrie types that contain V1 are ones+-- for empty types, which are adequately represented by EmptyTrie. Indeed,+-- if we offered an inhabited GTrie for a Void type, we'd run into trouble,+-- because then we'd falsely claim that the TrieMap from Void isn't null!+  gtrieLookup _ t               = case t of+  gtrieInsert _ _ t             = case t of+  gtrieDelete _ t               = case t of+  gtrieAlter _ _ t              = case t of+  gtrieSingleton k _            = case k of+  gtrieMap _ t                  = case t of+  gtrieTraverse _ t             = case t of+  gmapMaybeWithKey _ t          = case t of+  gfoldWithKey _ _ t            = case t of+  gtraverseWithKey _ t          = case t of+  gtraverseMaybeWithKey _ t     = case t of+  gmergeWithKey _ _ _ t _       = case t of   {-# INLINE gtrieLookup #-}   {-# INLINE gtrieInsert #-}   {-# INLINE gtrieDelete #-}+  {-# INLINE gtrieAlter #-}   {-# INLINE gtrieSingleton #-}   {-# INLINE gtrieMap #-}   {-# INLINE gtrieTraverse #-}   {-# INLINE gfoldWithKey #-}   {-# INLINE gtraverseWithKey #-}+  {-# INLINE gtraverseMaybeWithKey #-}   {-# INLINE gmergeWithKey #-}   {-# INLINE gmapMaybeWithKey #-} @@ -838,8 +1137,9 @@ -- Various instances for Trie ------------------------------------------------------------------------------ -instance (Show a, TrieKey  k) => Show (Trie  k a) where-  showsPrec = trieShowsPrec+instance (TrieKey k, Show k, Show a) => Show (Trie k a) where+  showsPrec d m  = showParen (d > 10) $+    showString "fromList " . shows (toList m)  instance (Show a, GTrieKeyShow f) => Show (GTrie f a) where   showsPrec = gtrieShowsPrec@@ -847,8 +1147,12 @@ instance TrieKey k => Functor (Trie k) where   fmap = trieMap -instance TrieKey k => Foldable (Trie k) where+instance TrieKey k => Foldable.Foldable (Trie k) where+  foldMap = Traversable.foldMapDefault   foldr f = trieFoldWithKey (\_ -> f)+#if MIN_VERSION_base(4,8,0)+  null = trieNull+#endif  instance TrieKey k => Traversable (Trie k) where   traverse = trieTraverse
+ src/Prelude.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE PackageImports #-}+-- | This hideous module lets us avoid dealing with the fact that+-- various functions haven't always been exported from the standard+-- Prelude.+module Prelude+  ( module Prel+#if !MIN_VERSION_base(4,18,0)+  , Applicative (..)+#endif+#if !MIN_VERSION_base(4,10,0)+  , liftA2+#endif+#if !MIN_VERSION_base(4,8,0)+  , Foldable (foldMap)+  , Traversable (traverse)+  , Word+  , (<$>)+#endif+  )+  where++import "base" Prelude as Prel+#if !MIN_VERSION_base(4,18,0)+import Control.Applicative (Applicative (..))+#endif++#if !MIN_VERSION_base(4,10,0)+import Control.Applicative (liftA2)+#endif++#if !MIN_VERSION_base(4,8,0)+import Data.Foldable (Foldable (..))+import Data.Traversable (Traversable (..))+import Data.Word (Word)+import Control.Applicative ((<$>))+#endif