packages feed

generic-trie 0.2 → 0.3

raw patch · 3 files changed

+1068/−817 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.GenericTrie: MkTrie :: (TrieRep k a) -> Trie k a
- Data.GenericTrie: class GTrieKey f
- Data.GenericTrie: genericDelete :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k) => k -> Trie k a -> Trie k a
- Data.GenericTrie: genericEmpty :: TrieRep k ~ TrieRepDefault k => Trie k a
- Data.GenericTrie: genericFoldWithKey :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k) => (k -> a -> r -> r) -> r -> Trie k a -> r
- Data.GenericTrie: genericInsert :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k) => k -> a -> Trie k a -> Trie k a
- Data.GenericTrie: genericLookup :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k) => k -> Trie k a -> Maybe a
- Data.GenericTrie: genericMapMaybeWithKey :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k) => (k -> a -> Maybe b) -> Trie k a -> Trie k b
- Data.GenericTrie: genericSingleton :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k) => k -> a -> Trie k a
- Data.GenericTrie: genericTraverseWithKey :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k, Applicative f) => (k -> a -> f b) -> Trie k a -> f (Trie k b)
- Data.GenericTrie: genericTrieMap :: (GTrieKey (Rep k), TrieRep k ~ TrieRepDefault k) => (a -> b) -> Trie k a -> Trie k b
- Data.GenericTrie: genericTrieNull :: TrieRep k ~ TrieRepDefault k => Trie k a -> Bool
- Data.GenericTrie: genericTrieShowsPrec :: (Show a, GTrieKeyShow (Rep k), TrieRep k ~ TrieRepDefault k) => Int -> Trie k a -> ShowS
- Data.GenericTrie: genericTrieTraverse :: (GTrieKey (Rep k), TrieRep k ~ TrieRepDefault k, Applicative f) => (a -> f b) -> Trie k a -> f (Trie k b)
- Data.GenericTrie: gfoldWithKey :: GTrieKey f => (f p -> a -> r -> r) -> r -> GTrie f a -> r
- Data.GenericTrie: gmapMaybeWithKey :: GTrieKey f => (f p -> a -> Maybe b) -> GTrie f a -> Maybe (GTrie f b)
- Data.GenericTrie: gmergeWithKey :: GTrieKey f => (f p -> a -> b -> Maybe c) -> (GTrie f a -> Maybe (GTrie f c)) -> (GTrie f b -> Maybe (GTrie f c)) -> GTrie f a -> GTrie f b -> Maybe (GTrie f c)
- Data.GenericTrie: gtraverseWithKey :: (GTrieKey f, Applicative m) => (f p -> a -> m b) -> GTrie f a -> m (GTrie f b)
- Data.GenericTrie: gtrieDelete :: GTrieKey f => f p -> GTrie f a -> Maybe (GTrie f a)
- Data.GenericTrie: gtrieInsert :: GTrieKey f => f p -> a -> GTrie f a -> GTrie f a
- Data.GenericTrie: gtrieLookup :: GTrieKey f => f p -> GTrie f a -> Maybe a
- Data.GenericTrie: gtrieMap :: GTrieKey f => (a -> b) -> GTrie f a -> GTrie f b
- Data.GenericTrie: gtrieSingleton :: GTrieKey f => f p -> a -> GTrie f a
- Data.GenericTrie: gtrieTraverse :: (GTrieKey f, Applicative m) => (a -> m b) -> GTrie f a -> m (GTrie f b)
- Data.GenericTrie: instance (Constructor c, GTrieKeyShow f) => GTrieKeyShow (M1 C c f)
- Data.GenericTrie: instance (GTrieKey f, GTrieKey g) => GTrieKey (f :*: g)
- Data.GenericTrie: instance (GTrieKey f, GTrieKey g) => GTrieKey (f :+: g)
- Data.GenericTrie: instance (GTrieKeyShow f, GTrieKeyShow g) => GTrieKeyShow (f :*: g)
- Data.GenericTrie: instance (GTrieKeyShow f, GTrieKeyShow g) => GTrieKeyShow (f :+: g)
- Data.GenericTrie: instance (Show a, GTrieKeyShow f) => Show (GTrie f a)
- Data.GenericTrie: instance (Show a, TrieKey k) => Show (Trie k a)
- Data.GenericTrie: instance (Show k, Ord k) => TrieKey (OrdKey k)
- Data.GenericTrie: instance (TrieKey a, TrieKey b) => TrieKey (Either a b)
- Data.GenericTrie: instance (TrieKey a, TrieKey b) => TrieKey (a, b)
- Data.GenericTrie: instance (TrieKey a, TrieKey b, TrieKey c) => TrieKey (a, b, c)
- Data.GenericTrie: instance Eq k => Eq (OrdKey k)
- Data.GenericTrie: instance GTrieKey U1
- Data.GenericTrie: instance GTrieKey V1
- Data.GenericTrie: instance GTrieKey f => Functor (GTrie f)
- Data.GenericTrie: instance GTrieKey f => GTrieKey (M1 i c f)
- Data.GenericTrie: instance GTrieKeyShow U1
- Data.GenericTrie: instance GTrieKeyShow V1
- Data.GenericTrie: instance GTrieKeyShow f => GTrieKeyShow (M1 D d f)
- Data.GenericTrie: instance GTrieKeyShow f => GTrieKeyShow (M1 S s f)
- Data.GenericTrie: instance Ord k => Ord (OrdKey k)
- Data.GenericTrie: instance Read k => Read (OrdKey k)
- Data.GenericTrie: instance Show k => Show (OrdKey k)
- Data.GenericTrie: instance TrieKey ()
- Data.GenericTrie: instance TrieKey Bool
- Data.GenericTrie: instance TrieKey Char
- Data.GenericTrie: instance TrieKey Int
- Data.GenericTrie: instance TrieKey Integer
- Data.GenericTrie: instance TrieKey k => Foldable (Trie k)
- Data.GenericTrie: instance TrieKey k => Functor (Trie k)
- Data.GenericTrie: instance TrieKey k => GTrieKey (K1 i k)
- Data.GenericTrie: instance TrieKey k => GTrieKeyShow (K1 i k)
- Data.GenericTrie: instance TrieKey k => Traversable (Trie k)
- Data.GenericTrie: instance TrieKey k => TrieKey (Maybe k)
- Data.GenericTrie: instance TrieKey k => TrieKey [k]
- Data.GenericTrie: lookup :: TrieKey k => k -> Trie k a -> Maybe a
- Data.GenericTrie: mergeWithKey :: TrieKey k => (k -> a -> b -> Maybe c) -> (Trie k a -> Trie k c) -> (Trie k b -> Trie k c) -> Trie k a -> Trie k b -> Trie k c
- Data.GenericTrie: newtype Trie k a
- Data.GenericTrie: trieMap :: TrieKey k => (a -> b) -> Trie k a -> Trie k b
- Data.GenericTrie: trieNull :: TrieKey k => Trie k a -> Bool
- Data.GenericTrie: trieShowsPrec :: (TrieKey k, Show a) => Int -> Trie k a -> ShowS
- Data.GenericTrie: trieTraverse :: (TrieKey k, Applicative f) => (a -> f b) -> Trie k a -> f (Trie k b)
- Data.GenericTrie: type TrieRepDefault k = Compose Maybe (GTrie (Rep k))
+ Data.GenericTrie: at :: (Functor f, TrieKey k) => k -> (Maybe a -> f (Maybe a)) -> Trie k a -> f (Trie k a)
+ Data.GenericTrie: data Trie k a
+ Data.GenericTrie: filter :: TrieKey k => (a -> Bool) -> Trie k a -> Trie k a
+ Data.GenericTrie: filterWithKey :: TrieKey k => (k -> a -> Bool) -> Trie k a -> Trie k a
+ Data.GenericTrie: fold :: TrieKey k => (a -> r -> r) -> r -> Trie k a -> r
+ Data.GenericTrie: fromListWith :: TrieKey k => (v -> v -> v) -> [(k, v)] -> Trie k v
+ Data.GenericTrie: fromListWith' :: TrieKey k => (v -> v -> v) -> [(k, v)] -> Trie k v
+ Data.GenericTrie: insertWith :: TrieKey k => (v -> v -> v) -> k -> v -> Trie k v -> Trie k v
+ Data.GenericTrie: insertWith' :: TrieKey k => (v -> v -> v) -> k -> v -> Trie k v -> Trie k v
+ Data.GenericTrie: null :: TrieKey k => Trie k a -> Bool
+ Data.GenericTrie.Internal: MkTrie :: (TrieRep k a) -> Trie k a
+ Data.GenericTrie.Internal: OrdKey :: k -> OrdKey k
+ Data.GenericTrie.Internal: class GTrieKey f
+ Data.GenericTrie.Internal: class TrieKey k where type family TrieRep k :: * -> * type instance TrieRep k = TrieRepDefault k trieEmpty = genericEmpty trieSingleton = genericSingleton trieNull = genericTrieNull trieLookup = genericLookup trieInsert = genericInsert trieDelete = genericDelete trieMap = genericTrieMap trieTraverse = genericTrieTraverse trieShowsPrec = genericTrieShowsPrec trieMapMaybeWithKey = genericMapMaybeWithKey trieFoldWithKey = genericFoldWithKey trieTraverseWithKey = genericTraverseWithKey trieMergeWithKey = genericMergeWithKey trieAt = genericAt
+ Data.GenericTrie.Internal: genericAt :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k, Functor f) => k -> (Maybe a -> f (Maybe a)) -> Trie k a -> f (Trie k a)
+ Data.GenericTrie.Internal: genericDelete :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k) => k -> Trie k a -> Trie k a
+ Data.GenericTrie.Internal: genericEmpty :: TrieRep k ~ TrieRepDefault k => Trie k a
+ Data.GenericTrie.Internal: genericFoldWithKey :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k) => (k -> a -> r -> r) -> r -> Trie k a -> r
+ Data.GenericTrie.Internal: genericInsert :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k) => k -> a -> Trie k a -> Trie k a
+ Data.GenericTrie.Internal: genericLookup :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k) => k -> Trie k a -> Maybe a
+ Data.GenericTrie.Internal: genericMapMaybeWithKey :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k) => (k -> a -> Maybe b) -> Trie k a -> Trie k b
+ Data.GenericTrie.Internal: genericSingleton :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k) => k -> a -> Trie k a
+ Data.GenericTrie.Internal: genericTraverseWithKey :: (GTrieKey (Rep k), Generic k, TrieRep k ~ TrieRepDefault k, Applicative f) => (k -> a -> f b) -> Trie k a -> f (Trie k b)
+ Data.GenericTrie.Internal: genericTrieMap :: (GTrieKey (Rep k), TrieRep k ~ TrieRepDefault k) => (a -> b) -> Trie k a -> Trie k b
+ Data.GenericTrie.Internal: genericTrieNull :: TrieRep k ~ TrieRepDefault k => Trie k a -> Bool
+ Data.GenericTrie.Internal: genericTrieShowsPrec :: (Show a, GTrieKeyShow (Rep k), TrieRep k ~ TrieRepDefault k) => Int -> Trie k a -> ShowS
+ Data.GenericTrie.Internal: genericTrieTraverse :: (GTrieKey (Rep k), TrieRep k ~ TrieRepDefault k, Applicative f) => (a -> f b) -> Trie k a -> f (Trie k b)
+ Data.GenericTrie.Internal: getOrdKey :: OrdKey k -> k
+ Data.GenericTrie.Internal: gfoldWithKey :: GTrieKey f => (f p -> a -> r -> r) -> r -> GTrie f a -> r
+ Data.GenericTrie.Internal: gmapMaybeWithKey :: GTrieKey f => (f p -> a -> Maybe b) -> GTrie f a -> Maybe (GTrie f b)
+ Data.GenericTrie.Internal: gmergeWithKey :: GTrieKey f => (f p -> a -> b -> Maybe c) -> (GTrie f a -> Maybe (GTrie f c)) -> (GTrie f b -> Maybe (GTrie f c)) -> GTrie f a -> GTrie f b -> Maybe (GTrie f c)
+ Data.GenericTrie.Internal: gtraverseWithKey :: (GTrieKey f, Applicative m) => (f p -> a -> m b) -> GTrie f a -> m (GTrie f b)
+ Data.GenericTrie.Internal: gtrieAt :: (GTrieKey f, Functor m) => (Maybe (GTrie f a) -> r) -> f p -> (Maybe a -> m (Maybe a)) -> GTrie f a -> m r
+ Data.GenericTrie.Internal: gtrieDelete :: GTrieKey f => f p -> GTrie f a -> Maybe (GTrie f a)
+ Data.GenericTrie.Internal: gtrieInsert :: GTrieKey f => f p -> a -> GTrie f a -> GTrie f a
+ Data.GenericTrie.Internal: gtrieLookup :: GTrieKey f => f p -> GTrie f a -> Maybe a
+ Data.GenericTrie.Internal: gtrieMap :: GTrieKey f => (a -> b) -> GTrie f a -> GTrie f b
+ Data.GenericTrie.Internal: gtrieSingleton :: GTrieKey f => f p -> a -> GTrie f a
+ Data.GenericTrie.Internal: gtrieTraverse :: (GTrieKey f, Applicative m) => (a -> m b) -> GTrie f a -> m (GTrie f b)
+ Data.GenericTrie.Internal: instance (Constructor c, GTrieKeyShow f) => GTrieKeyShow (M1 C c f)
+ Data.GenericTrie.Internal: instance (GTrieKey f, GTrieKey g) => GTrieKey (f :*: g)
+ Data.GenericTrie.Internal: instance (GTrieKey f, GTrieKey g) => GTrieKey (f :+: g)
+ Data.GenericTrie.Internal: instance (GTrieKeyShow f, GTrieKeyShow g) => GTrieKeyShow (f :*: g)
+ Data.GenericTrie.Internal: instance (GTrieKeyShow f, GTrieKeyShow g) => GTrieKeyShow (f :+: g)
+ Data.GenericTrie.Internal: instance (Show a, GTrieKeyShow f) => Show (GTrie f a)
+ Data.GenericTrie.Internal: instance (Show a, TrieKey k) => Show (Trie k a)
+ Data.GenericTrie.Internal: instance (Show k, Ord k) => TrieKey (OrdKey k)
+ Data.GenericTrie.Internal: instance (TrieKey a, TrieKey b) => TrieKey (Either a b)
+ Data.GenericTrie.Internal: instance (TrieKey a, TrieKey b) => TrieKey (a, b)
+ Data.GenericTrie.Internal: instance (TrieKey a, TrieKey b, TrieKey c) => TrieKey (a, b, c)
+ Data.GenericTrie.Internal: instance (TrieKey a, TrieKey b, TrieKey c, TrieKey d) => TrieKey (a, b, c, d)
+ Data.GenericTrie.Internal: instance (TrieKey a, TrieKey b, TrieKey c, TrieKey d, TrieKey e) => TrieKey (a, b, c, d, e)
+ Data.GenericTrie.Internal: instance Eq k => Eq (OrdKey k)
+ Data.GenericTrie.Internal: instance GTrieKey U1
+ Data.GenericTrie.Internal: instance GTrieKey V1
+ Data.GenericTrie.Internal: instance GTrieKey f => Functor (GTrie f)
+ Data.GenericTrie.Internal: instance GTrieKey f => GTrieKey (M1 i c f)
+ Data.GenericTrie.Internal: instance GTrieKeyShow U1
+ Data.GenericTrie.Internal: instance GTrieKeyShow V1
+ Data.GenericTrie.Internal: instance GTrieKeyShow f => GTrieKeyShow (M1 D d f)
+ Data.GenericTrie.Internal: instance GTrieKeyShow f => GTrieKeyShow (M1 S s f)
+ Data.GenericTrie.Internal: instance Ord k => Ord (OrdKey k)
+ Data.GenericTrie.Internal: instance Read k => Read (OrdKey k)
+ Data.GenericTrie.Internal: instance Show k => Show (OrdKey k)
+ Data.GenericTrie.Internal: instance TrieKey ()
+ Data.GenericTrie.Internal: instance TrieKey Bool
+ Data.GenericTrie.Internal: instance TrieKey Char
+ Data.GenericTrie.Internal: instance TrieKey Int
+ Data.GenericTrie.Internal: instance TrieKey Integer
+ Data.GenericTrie.Internal: instance TrieKey k => Foldable (Trie k)
+ Data.GenericTrie.Internal: instance TrieKey k => Functor (Trie k)
+ Data.GenericTrie.Internal: instance TrieKey k => GTrieKey (K1 i k)
+ Data.GenericTrie.Internal: instance TrieKey k => GTrieKeyShow (K1 i k)
+ Data.GenericTrie.Internal: instance TrieKey k => Traversable (Trie k)
+ Data.GenericTrie.Internal: instance TrieKey k => TrieKey (Maybe k)
+ Data.GenericTrie.Internal: instance TrieKey k => TrieKey [k]
+ Data.GenericTrie.Internal: newtype OrdKey k
+ Data.GenericTrie.Internal: newtype Trie k a
+ Data.GenericTrie.Internal: trieAt :: (TrieKey k, Functor f) => k -> (Maybe a -> f (Maybe a)) -> Trie k a -> f (Trie k a)
+ Data.GenericTrie.Internal: trieDelete :: TrieKey k => k -> Trie k a -> Trie k a
+ Data.GenericTrie.Internal: trieEmpty :: TrieKey k => Trie k a
+ Data.GenericTrie.Internal: trieFoldWithKey :: TrieKey k => (k -> a -> r -> r) -> r -> Trie k a -> r
+ Data.GenericTrie.Internal: trieInsert :: TrieKey k => k -> a -> Trie k a -> Trie k a
+ Data.GenericTrie.Internal: trieLookup :: TrieKey k => k -> Trie k a -> Maybe a
+ Data.GenericTrie.Internal: trieMap :: TrieKey k => (a -> b) -> Trie k a -> Trie k b
+ Data.GenericTrie.Internal: trieMapMaybeWithKey :: TrieKey k => (k -> a -> Maybe b) -> Trie k a -> Trie k b
+ Data.GenericTrie.Internal: trieMergeWithKey :: TrieKey k => (k -> a -> b -> Maybe c) -> (Trie k a -> Trie k c) -> (Trie k b -> Trie k c) -> Trie k a -> Trie k b -> Trie k c
+ Data.GenericTrie.Internal: trieNull :: TrieKey k => Trie k a -> Bool
+ Data.GenericTrie.Internal: trieShowsPrec :: (TrieKey k, Show a) => Int -> Trie k a -> ShowS
+ Data.GenericTrie.Internal: trieSingleton :: TrieKey k => k -> a -> Trie k a
+ Data.GenericTrie.Internal: trieTraverse :: (TrieKey k, Applicative f) => (a -> f b) -> Trie k a -> f (Trie k b)
+ Data.GenericTrie.Internal: trieTraverseWithKey :: (TrieKey k, Applicative f) => (k -> a -> f b) -> Trie k a -> f (Trie k b)
+ Data.GenericTrie.Internal: type TrieRepDefault k = Compose Maybe (GTrie (Rep k))
- Data.GenericTrie: class TrieKey k where type family TrieRep k :: * -> * type instance TrieRep k = TrieRepDefault k empty = genericEmpty singleton = genericSingleton trieNull = genericTrieNull lookup = genericLookup insert = genericInsert delete = genericDelete trieMap = genericTrieMap trieTraverse = genericTrieTraverse trieShowsPrec = genericTrieShowsPrec mapMaybeWithKey = genericMapMaybeWithKey foldWithKey = genericFoldWithKey traverseWithKey = genericTraverseWithKey mergeWithKey = genericMergeWithKey
+ Data.GenericTrie: class TrieKey k where type instance TrieRep k = TrieRepDefault k trieEmpty = genericEmpty trieSingleton = genericSingleton trieNull = genericTrieNull trieLookup = genericLookup trieInsert = genericInsert trieDelete = genericDelete trieMap = genericTrieMap trieTraverse = genericTrieTraverse trieShowsPrec = genericTrieShowsPrec trieMapMaybeWithKey = genericMapMaybeWithKey trieFoldWithKey = genericFoldWithKey trieTraverseWithKey = genericTraverseWithKey trieMergeWithKey = genericMergeWithKey trieAt = genericAt

Files

generic-trie.cabal view
@@ -1,5 +1,5 @@ name:                generic-trie-version:             0.2+version:             0.3 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@@ -20,7 +20,8 @@ bug-reports:         http://github.com/glguy/tries/issues  library-  exposed-modules:     Data.GenericTrie+  exposed-modules:     Data.GenericTrie,+                       Data.GenericTrie.Internal   build-depends:       base             >= 4.5     && < 4.9,                        transformers     >= 0.2     && < 0.5,                        containers       >= 0.4.2.1 && < 0.6
src/Data/GenericTrie.hs view
@@ -1,27 +1,26 @@-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE UndecidableInstances #-} -- allows the TypeRep default+{-# LANGUAGE Safe #-}  {- | -This module implements an interface for working with "tries".-A key in the trie represents a distinct path through the trie.-This can provide benefits when using very large and possibly-very similar keys where comparing for order can become-expensive, and storing the various keys could be inefficient.+This module implements an interface for working with maps. -For primitive types like 'Int', this library will select efficient-implementations automatically.+For primitive types, like 'Int', the library automatically selects+an efficient implementation (e.g., an "IntMap"). +For complex structured types, the library uses an implementation+based on tries: this is useful when using large and similar keys where+comparing for order may become expensive, and storing the distinct+keys would be inefficient.++The 'OrdKey' type allows for maps with complex keys,+where the keys are compared based on order, rather than using the+trie implementation.+ All methods of 'TrieKey' can be derived automatically using-a 'Generic' instance.+a 'GHC.Generics.Generic' instance.  @-data Demo = DemoC1 'Int' | DemoC2 'Int' 'Char'  deriving 'Generic'+data Demo = DemoC1 'Int' | DemoC2 'Int' 'Char'  deriving 'GHC.Generics.Generic'  instance 'TrieKey' Demo @@@ -31,13 +30,42 @@ module Data.GenericTrie   (   -- * Trie interface-    Trie(..)+    Trie+  , TrieKey++  -- ** Construction+  , empty+  , singleton+  , fromList+  , fromListWith+  , fromListWith'++  -- ** Updates   , alter+  , insert+  , insertWith+  , insertWith'+  , delete+  , at ++  -- ** Queries   , member   , notMember-  , fromList+  , null++  -- ** Folding+  , foldWithKey+  , fold   , toList++  -- ** Traversing+  , traverseWithKey   , mapMaybe+  , mapMaybeWithKey+  , filter+  , filterWithKey++  -- ** Combining maps   , union   , unionWith   , unionWithKey@@ -47,817 +75,142 @@   , difference   , differenceWith   , differenceWithKey-  , TrieKey(..)-  -- * Manual ord key instance selector++  -- * Keys using 'Ord'   , OrdKey(..)-  -- * Generic derivation implementation-  , genericTrieNull-  , genericTrieMap-  , genericTrieTraverse-  , genericTrieShowsPrec-  , genericInsert-  , genericLookup-  , genericDelete-  , genericMapMaybeWithKey-  , genericSingleton-  , genericEmpty-  , genericFoldWithKey-  , genericTraverseWithKey-  , TrieRepDefault-  , GTrieKey(..)-  , GTrie(..)   ) where --import Control.Applicative (Applicative, liftA2)-import Data.Char (chr, ord)-import Data.Coerce (coerce)-import Data.Foldable (Foldable)-import Data.Functor.Compose (Compose(..))-import Data.IntMap (IntMap)+import Control.Applicative (Applicative) import Data.List (foldl')-import Data.Map (Map) import Data.Maybe (isNothing, isJust)-import Data.Traversable (Traversable,traverse)-import GHC.Generics-import Prelude hiding (lookup)-import qualified Data.Foldable as Foldable-import qualified Data.IntMap as IntMap-import qualified Data.Map as Map----- | Keys that support prefix-trie map operations.------ All operations can be automatically derived from a 'Generic' instance.-class TrieKey k where--  -- | Type of the representation of tries for this key.-  type TrieRep k :: * -> *--  -- | Construct an empty trie-  empty :: Trie k a--  -- | Test for an empty trie-  trieNull :: Trie k a -> Bool--  -- | Lookup element from trie-  lookup :: k -> Trie k a -> Maybe a--  -- | Insert element into trie-  insert :: k -> a -> Trie k a -> Trie k a--  -- | Delete element from trie-  delete :: k -> Trie k a -> Trie k a--  -- | Construct a trie holding a single value-  singleton :: k -> a -> Trie k a--  -- | Apply a function to all values stored in a trie-  trieMap :: (a -> b) -> Trie k a -> Trie k b--  -- | 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.-  mapMaybeWithKey :: (k -> a -> Maybe b) -> Trie k a -> Trie k b--  -- | Fold a trie with a function of both key and value.-  foldWithKey :: (k -> a -> r -> r) -> r -> Trie k a -> r--  -- | Traverse a trie with a function of both key and value.-  traverseWithKey :: Applicative f => (k -> a -> f b) -> Trie k a -> f (Trie k b)--  mergeWithKey :: (k -> a -> b -> Maybe c) ->-                  (Trie k a -> Trie k c) ->-                  (Trie k b -> Trie k c) ->-                  Trie k a -> Trie k b -> Trie k c---  -- Defaults using 'Generic'--  type instance TrieRep k = TrieRepDefault k--  default empty :: ( TrieRep k ~ TrieRepDefault k) => Trie k a-  empty = genericEmpty--  default singleton ::-    ( GTrieKey (Rep k), Generic k , TrieRep k ~ TrieRepDefault k) =>-    k -> a -> Trie k a-  singleton = genericSingleton--  default trieNull ::-    ( TrieRep k ~ TrieRepDefault k) =>-    Trie k a -> Bool-  trieNull = genericTrieNull--  default lookup ::-    ( GTrieKey (Rep k), Generic k , TrieRep k ~ TrieRepDefault k) =>-    k -> Trie k a -> Maybe a-  lookup = genericLookup--  default insert ::-    ( GTrieKey (Rep k), Generic k , TrieRep k ~ TrieRepDefault k) =>-    k -> a -> Trie k a -> Trie k a-  insert = genericInsert--  default delete ::-    ( GTrieKey (Rep k), Generic k , TrieRep k ~ TrieRepDefault k) =>-    k -> Trie k a -> Trie k a-  delete = genericDelete--  default trieMap ::-    ( GTrieKey (Rep k) , TrieRep k ~ TrieRepDefault k) =>-    (a -> b) -> Trie k a -> Trie k b-  trieMap = genericTrieMap--  default trieTraverse ::-    ( GTrieKey (Rep k) , TrieRep k ~ TrieRepDefault k , Applicative f) =>-    (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 mapMaybeWithKey ::-    ( GTrieKey (Rep k) , Generic k, TrieRep k ~ TrieRepDefault k) =>-    (k -> a -> Maybe b) -> Trie k a -> Trie k b-  mapMaybeWithKey = genericMapMaybeWithKey--  default foldWithKey ::-    ( GTrieKey (Rep k) , TrieRep k ~ TrieRepDefault k, Generic k) =>-    (k -> a -> r -> r) -> r -> Trie k a -> r-  foldWithKey = genericFoldWithKey--  default traverseWithKey ::-    ( GTrieKey (Rep k) , TrieRep k ~ TrieRepDefault k, Generic k, Applicative f) =>-    (k -> a -> f b) -> Trie k a -> f (Trie k b)-  traverseWithKey = genericTraverseWithKey--  default mergeWithKey ::-    ( GTrieKey (Rep k) , TrieRep k ~ TrieRepDefault k, Generic k ) =>-    (k -> a -> b -> Maybe c) ->-    (Trie k a -> Trie k c) ->-    (Trie k b -> Trie k c) ->-    Trie k a -> Trie k b -> Trie k c-  mergeWithKey = genericMergeWithKey---- | The default implementation of a 'TrieRep' is 'GTrie' wrapped in--- a 'Maybe'. This wrapping is due to the 'GTrie' being a non-empty--- trie allowing all the of the "emptiness" to be represented at the--- top level for any given generically implemented key.-type TrieRepDefault k = Compose Maybe (GTrie (Rep k))---- | Effectively an associated datatype of tries indexable by keys of type @k@.--- By using a separate newtype wrapper around the associated type synonym we're--- able to use the same 'MkTrie' constructor for all of the generic--- implementations while still getting the injectivity of a new type.-newtype Trie k a = MkTrie (TrieRep k a)------------------------------------------------------------------------------------ Manually derived instances for base types----------------------------------------------------------------------------------- | 'Int' tries are implemented with 'IntMap'.-instance TrieKey Int where-  type TrieRep Int              = IntMap-  lookup k (MkTrie x)           = IntMap.lookup k x-  insert k v (MkTrie t)         = MkTrie (IntMap.insert k v t)-  delete k (MkTrie t)           = MkTrie (IntMap.delete k t)-  empty                         = MkTrie IntMap.empty-  singleton 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-  mapMaybeWithKey f (MkTrie x)  = MkTrie (IntMap.mapMaybeWithKey f x)-  foldWithKey f z (MkTrie x)    = IntMap.foldWithKey f z x-  traverseWithKey f (MkTrie x)  = fmap MkTrie (IntMap.traverseWithKey f x)-  mergeWithKey f g h (MkTrie x) (MkTrie y) = MkTrie (IntMap.mergeWithKey f (coerce g) (coerce h) x y)-  {-# INLINE empty #-}-  {-# INLINE insert #-}-  {-# INLINE lookup #-}-  {-# INLINE delete #-}-  {-# INLINE foldWithKey #-}-  {-# INLINE trieTraverse #-}-  {-# INLINE trieNull #-}-  {-# INLINE trieMap #-}-  {-# INLINE mergeWithKey #-}---- | 'Integer' tries are implemented with 'Map'.-instance TrieKey Integer where-  type TrieRep Integer          = Map Integer-  lookup k (MkTrie t)           = Map.lookup k t-  insert k v (MkTrie t)         = MkTrie (Map.insert k v t)-  delete k (MkTrie t)           = MkTrie (Map.delete k t)-  empty                         = MkTrie Map.empty-  singleton 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-  mapMaybeWithKey f (MkTrie x)  = MkTrie (Map.mapMaybeWithKey f x)-  foldWithKey f z (MkTrie x)    = Map.foldrWithKey f z x-  traverseWithKey f (MkTrie x)  = fmap MkTrie (Map.traverseWithKey f x)-  mergeWithKey f g h (MkTrie x) (MkTrie y) = MkTrie (Map.mergeWithKey f (coerce g) (coerce h) x y)-  {-# INLINE empty #-}-  {-# INLINE insert #-}-  {-# INLINE lookup #-}-  {-# INLINE delete #-}-  {-# INLINE trieNull #-}-  {-# INLINE trieMap #-}-  {-# INLINE foldWithKey #-}-  {-# INLINE mergeWithKey #-}-  {-# INLINE trieTraverse #-}---- | 'Char tries are implemented with 'IntMap'.-instance TrieKey Char where-  type TrieRep Char             = IntMap-  lookup k (MkTrie t)           = IntMap.lookup (ord k) t-  delete k (MkTrie t)           = MkTrie (IntMap.delete (ord k) t)-  insert k v (MkTrie t)         = MkTrie (IntMap.insert (ord k) v t)-  empty                         = MkTrie IntMap.empty-  singleton 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-  mapMaybeWithKey f (MkTrie x)  = MkTrie (IntMap.mapMaybeWithKey (f . chr) x)-  foldWithKey f z (MkTrie x)    = IntMap.foldrWithKey (f . chr) z x-  traverseWithKey f (MkTrie x)  = fmap MkTrie (IntMap.traverseWithKey (f . chr) x)-  mergeWithKey f g h (MkTrie x) (MkTrie y) = MkTrie (IntMap.mergeWithKey (f . chr) (coerce g) (coerce h) x y)-  {-# INLINE empty #-}-  {-# INLINE insert #-}-  {-# INLINE lookup #-}-  {-# INLINE delete #-}-  {-# INLINE trieNull #-}-  {-# INLINE trieTraverse #-}-  {-# INLINE trieMap #-}-  {-# INLINE foldWithKey #-}-  {-# INLINE mergeWithKey #-}--newtype OrdKey k = OrdKey { getOrdKey :: k }-  deriving (Read, Show, Eq, Ord)---- | 'OrdKey' tries are implemented with 'Map', this is--- 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-  type TrieRep (OrdKey k)               = Map k-  lookup (OrdKey k) (MkTrie x)          = Map.lookup k x-  insert (OrdKey k) v (MkTrie x)        = MkTrie (Map.insert k v x)-  delete (OrdKey k) (MkTrie x)          = MkTrie (Map.delete k x)-  empty                                 = MkTrie Map.empty-  singleton (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-  mapMaybeWithKey f (MkTrie x)          = MkTrie (Map.mapMaybeWithKey (f . OrdKey) x)-  foldWithKey f z (MkTrie x)            = Map.foldrWithKey (f . OrdKey) z x-  traverseWithKey f (MkTrie x)          = fmap MkTrie (Map.traverseWithKey (f . OrdKey) x)-  mergeWithKey f g h (MkTrie x) (MkTrie y) = MkTrie (Map.mergeWithKey (f . OrdKey) (coerce g) (coerce h) x y)-  {-# INLINE empty #-}-  {-# INLINE insert #-}-  {-# INLINE lookup #-}-  {-# INLINE delete #-}-  {-# INLINE foldWithKey #-}-  {-# INLINE trieNull #-}-  {-# INLINE trieMap #-}-  {-# INLINE trieTraverse #-}-  {-# INLINE mergeWithKey #-}-  {-# INLINE trieShowsPrec #-}----------------------------------------------------------------------------------- Automatically derived instances for common types---------------------------------------------------------------------------------instance                                      TrieKey ()-instance                                      TrieKey Bool-instance TrieKey k                         => TrieKey (Maybe k)-instance (TrieKey a, TrieKey b)            => TrieKey (Either a b)-instance (TrieKey a, TrieKey b)            => TrieKey (a,b)-instance (TrieKey a, TrieKey b, TrieKey c) => TrieKey (a,b,c)-instance TrieKey k                         => TrieKey [k]----------------------------------------------------------------------------------- Generic 'TrieKey' method implementations----------------------------------------------------------------------------------- | Generic implementation of 'lookup'. This is the default implementation.-genericLookup ::-    ( GTrieKey (Rep k), Generic k-    , TrieRep k ~ TrieRepDefault k-    ) =>-    k -> Trie k a -> Maybe a-genericLookup k (MkTrie (Compose t)) = gtrieLookup (from k) =<< t-{-# INLINABLE genericLookup #-}---- | Generic implementation of 'trieNull'. This is the default implementation.-genericTrieNull ::-    ( TrieRep k ~ TrieRepDefault k-    ) =>-    Trie k a -> Bool-genericTrieNull (MkTrie (Compose mb)) = isNothing mb-{-# INLINABLE genericTrieNull #-}---- | Generic implementation of 'singleton'. This is the default implementation.-genericSingleton ::-    ( GTrieKey (Rep k), Generic k-    , TrieRep k ~ TrieRepDefault k-    ) =>-    k -> a -> Trie k a-genericSingleton k v = MkTrie $ Compose $ Just $! gtrieSingleton (from k) v-{-# INLINABLE genericSingleton #-}---- | Generic implementation of 'empty'. This is the default implementation.-genericEmpty ::-    ( TrieRep k ~ TrieRepDefault k-    ) =>-    Trie k a-genericEmpty = MkTrie (Compose Nothing)-{-# INLINABLE genericEmpty #-}---- | Generic implementation of 'insert'. This is the default implementation.-genericInsert ::-    ( GTrieKey (Rep k), Generic k-    , TrieRep k ~ TrieRepDefault k-    ) =>-    k -> a -> Trie k a -> Trie k a-genericInsert k v (MkTrie (Compose m)) =-  case m of-    Nothing -> MkTrie (Compose (Just $! gtrieSingleton (from k) v))-    Just t  -> MkTrie (Compose (Just $! gtrieInsert (from k) v t))-{-# INLINABLE genericInsert #-}---- | Generic implementation of 'delete'. This is the default implementation.-genericDelete ::-    ( GTrieKey (Rep k), Generic k-    , TrieRep k ~ TrieRepDefault k-    ) =>-    k -> Trie k a -> Trie k a-genericDelete k (MkTrie (Compose m)) = MkTrie (Compose (gtrieDelete (from k) =<< m))-{-# INLINABLE genericDelete #-}---- | Generic implementation of 'trieMap'. This is the default implementation.-genericTrieMap ::-    ( GTrieKey (Rep k)-    , TrieRep k ~ TrieRepDefault k-    ) =>-    (a -> b) -> Trie k a -> Trie k b-genericTrieMap f (MkTrie (Compose x)) = MkTrie (Compose (fmap (gtrieMap f) $! x))-{-# INLINABLE genericTrieMap #-}----- | Generic implementation of 'trieTraverse'. This is the default implementation.-genericTrieTraverse ::-    ( GTrieKey (Rep k)-    , TrieRep k ~ TrieRepDefault k-    , Applicative f-    ) =>-    (a -> f b) -> Trie k a -> f (Trie k b)-genericTrieTraverse f (MkTrie (Compose x)) =-  fmap (MkTrie . Compose) (traverse (gtrieTraverse f) x)-{-# INLINABLE genericTrieTraverse #-}---- | Generic implementation of 'trieShowsPrec'. This is the default implementation.-genericTrieShowsPrec ::-    ( Show a, GTrieKeyShow (Rep k)-    , TrieRep k ~ TrieRepDefault k-    ) =>-    Int -> Trie k a -> ShowS-genericTrieShowsPrec p (MkTrie (Compose m)) =-  case m of-    Just x  -> showsPrec p x-    Nothing -> showString "()"-{-# INLINABLE genericTrieShowsPrec #-}---- | Generic implementation of 'mapMaybe'. This is the default implementation.-genericMapMaybeWithKey ::-    ( GTrieKey (Rep k), Generic k-    , TrieRep k ~ TrieRepDefault k-    ) =>-    (k -> a -> Maybe b) -> Trie k a -> Trie k b-genericMapMaybeWithKey f (MkTrie (Compose x)) = MkTrie (Compose (gmapMaybeWithKey (f . to) =<< x))-{-# INLINABLE genericMapMaybeWithKey #-}---- | Generic implementation of 'foldWithKey'. This is the default implementation.-genericFoldWithKey ::-    ( GTrieKey (Rep k), Generic k-    , TrieRep k ~ TrieRepDefault k-    ) =>-    (k -> a -> r -> r) -> r -> Trie k a -> r-genericFoldWithKey f z (MkTrie (Compose m)) =-  case m of-    Nothing -> z-    Just x  -> gfoldWithKey (f . to) z x-{-# INLINABLE genericFoldWithKey #-}---- | Generic implementation of 'traverseWithKey'. This is the default implementation.-genericTraverseWithKey ::-    ( GTrieKey (Rep k), Generic k-    , TrieRep k ~ TrieRepDefault k-    , Applicative f-    ) =>-    (k -> a -> f b) -> Trie k a -> f (Trie k b)-genericTraverseWithKey f (MkTrie (Compose m)) = fmap (MkTrie . Compose) (traverse (gtraverseWithKey (f . to)) m)-{-# INLINABLE genericTraverseWithKey #-}---- | Generic implementation of 'mergeWithKey'. This is the default implementation.-genericMergeWithKey ::-    ( GTrieKey (Rep k), Generic k-    , TrieRep k ~ TrieRepDefault k-    ) =>-    (k -> a -> b -> Maybe c) -> (Trie k a -> Trie k c) -> (Trie k b -> Trie k c) ->-    Trie k a -> Trie k b -> Trie k c-genericMergeWithKey f g h (MkTrie (Compose x)) (MkTrie (Compose y)) =-  case (x,y) of-    (Nothing, Nothing) -> MkTrie (Compose Nothing)-    (Just{} , Nothing) -> g (MkTrie (Compose x))-    (Nothing, Just{} ) -> h (MkTrie (Compose y))-    (Just x', Just y') -> MkTrie (Compose (gmergeWithKey (f . to) (aux g) (aux h) x' y'))-      where-      aux k t = case k (MkTrie (Compose (Just t))) of-                  MkTrie (Compose r) -> r-{-# INLINABLE genericMergeWithKey #-}+import Prelude hiding (lookup, null, filter) +import Data.GenericTrie.Internal  --------------------------------------------------------------------------------- Generic implementation class+-- Various helpers ------------------------------------------------------------------------------ --- | Mapping of generic representation of keys to trie structures.-data    family   GTrie (f :: * -> *) a-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)-                                        | STrieB !(GTrie f a) !(GTrie g a)-newtype instance GTrie (f :*: g)  a     = PTrie (GTrie f (GTrie g a))-newtype instance GTrie (K1 i k)   a     = KTrie (Trie k a)-newtype instance GTrie U1         a     = UTrie a-data    instance GTrie V1         a--instance GTrieKey f => Functor (GTrie f) where-  fmap = gtrieMap---- | TrieKey operations on Generic representations used to provide--- the default implementations of tries.-class GTrieKey f where-  gtrieLookup    :: f p -> GTrie f a -> Maybe a-  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)-  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)-  gmergeWithKey  :: (f p -> a -> b -> Maybe c) ->-                    (GTrie f a -> Maybe (GTrie f c)) ->-                    (GTrie f b -> Maybe (GTrie f c)) ->-                    GTrie f a -> GTrie f b -> Maybe (GTrie f c)---- | The 'GTrieKeyShow' class provides generic implementations--- of 'showsPrec'. This class is separate due to its implementation--- varying for diferent kinds of metadata.-class GTrieKeyShow f where-  gtrieShowsPrec :: Show a => Int -> GTrie f a -> ShowS+-- | Construct a trie from a list of key-value pairs+fromList :: TrieKey k => [(k,v)] -> Trie k v+fromList = foldl' (\acc (k,v) -> insert k v acc) empty ---------------------------------------------------------------------------------- Generic implementation for metadata-------------------------------------------------------------------------------+-- | Construct a trie from a list of key-value pairs.+-- The given function is used to combine values at the+-- same key.+fromListWith :: TrieKey k => (v -> v -> v) -> [(k,v)] -> Trie k v+fromListWith f = foldl' (\acc (k,v) -> insertWith f k v acc) empty --- | Generic metadata is skipped in trie representation and operations.-instance GTrieKey f => GTrieKey (M1 i c f) where-  gtrieLookup (M1 k) (MTrie x)  = gtrieLookup k x-  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)-  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)-  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 gtrieMap #-}-  {-# INLINE gmapMaybeWithKey #-}-  {-# INLINE gtrieTraverse #-}-  {-# INLINE gfoldWithKey #-}-  {-# INLINE gtraverseWithKey #-}+-- | Version of 'fromListWith' which is strict in the result of+-- the combining function.+fromListWith' :: TrieKey k => (v -> v -> v) -> [(k,v)] -> Trie k v+fromListWith' f = foldl' (\acc (k,v) -> insertWith' f k v acc) empty -data MProxy c (f :: * -> *) a = MProxy+-- | Construct an empty trie+empty :: TrieKey k => Trie k a+empty = trieEmpty+{-# INLINE empty #-} -instance GTrieKeyShow f => GTrieKeyShow (M1 D d f) where-  gtrieShowsPrec p (MTrie x)    = showsPrec p x-instance (Constructor c, GTrieKeyShow f) => GTrieKeyShow (M1 C c f) where-  gtrieShowsPrec p (MTrie x)    = showParen (p > 10)-                                $ showString "Con "-                                . shows (conName (MProxy :: MProxy c f ()))-                                . showString " "-                                . showsPrec 11 x-instance GTrieKeyShow f => GTrieKeyShow (M1 S s f) where-  gtrieShowsPrec p (MTrie x)    = showsPrec p x+-- | Test for an empty trie+null :: TrieKey k => Trie k a -> Bool+null = trieNull+{-# INLINE null #-} ---------------------------------------------------------------------------------- Generic implementation for fields-------------------------------------------------------------------------------+-- | Lookup an element from a trie+lookup :: TrieKey k => k -> Trie k a -> Maybe a+lookup = trieLookup+{-# INLINE lookup #-} -checkNull :: TrieKey k => Trie k a -> Maybe (Trie k a)-checkNull x-  | trieNull x = Nothing-  | otherwise  = Just x+-- | Lens for the value at a given key+at :: (Functor f, TrieKey k) => k -> (Maybe a -> f (Maybe a)) -> Trie k a -> f (Trie k a)+at = trieAt+{-# INLINE at #-} --- | Generic fields are represented by tries of the field type.-instance TrieKey k => GTrieKey (K1 i k) where-  gtrieLookup (K1 k) (KTrie x)          = lookup k x-  gtrieInsert (K1 k) v (KTrie t)        = KTrie (insert k v t)-  gtrieSingleton (K1 k) v               = KTrie (singleton k v)-  gtrieDelete (K1 k) (KTrie t)          = fmap KTrie (checkNull (delete k t))-  gtrieMap f (KTrie x)                  = KTrie (trieMap f x)-  gtrieTraverse f (KTrie x)             = fmap KTrie (traverse f x)-  gmapMaybeWithKey f (KTrie x)          = fmap KTrie (checkNull (mapMaybeWithKey (f . K1) x))-  gfoldWithKey f z (KTrie x)            = foldWithKey (f . K1) z x-  gtraverseWithKey f (KTrie x)          = fmap KTrie (traverseWithKey (f . K1) x)-  gmergeWithKey f g h (KTrie x) (KTrie y) = fmap KTrie (checkNull (mergeWithKey (f . K1) g' h' x y))-     where-     g' t = case g (KTrie t) of-              Just (KTrie t') -> t'-              Nothing         -> empty-     h' t = case h (KTrie t) of-              Just (KTrie t') -> t'-              Nothing         -> empty-  {-# INLINE gtrieLookup #-}-  {-# INLINE gtrieInsert #-}-  {-# INLINE gtrieSingleton #-}-  {-# INLINE gtrieDelete #-}-  {-# INLINE gtrieMap #-}-  {-# INLINE gtrieTraverse #-}-  {-# INLINE gfoldWithKey #-}-  {-# INLINE gtraverseWithKey #-}-  {-# INLINE gmergeWithKey #-}-  {-# INLINE gmapMaybeWithKey #-}+-- | Insert an element into a trie+insert :: TrieKey k => k -> a -> Trie k a -> Trie k a+insert = trieInsert+{-# INLINE insert #-} -instance TrieKey k => GTrieKeyShow (K1 i k) where-  gtrieShowsPrec p (KTrie x)            = showsPrec p x+-- | Delete an element from a trie+delete :: TrieKey k => k -> Trie k a -> Trie k a+delete = trieDelete+{-# INLINE delete #-} ---------------------------------------------------------------------------------- Generic implementation for products-------------------------------------------------------------------------------+-- | Construct a trie holding a single value+singleton :: TrieKey k => k -> a -> Trie k a+singleton = trieSingleton+{-# INLINE singleton #-} --- | Generic products are represented by tries of tries.-instance (GTrieKey f, GTrieKey g) => GTrieKey (f :*: g) where+-- | Apply a function to the values of a trie and keep the elements+-- of the trie that result in a 'Just' value.+mapMaybeWithKey :: TrieKey k => (k -> a -> Maybe b) -> Trie k a -> Trie k b+mapMaybeWithKey = trieMapMaybeWithKey+{-# INLINE mapMaybeWithKey #-} -  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))-  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)-  gmapMaybeWithKey f (PTrie x)          = fmap PTrie (gmapMaybeWithKey (\i -> gmapMaybeWithKey (\j -> f (i:*:j))) x)-  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)-  gmergeWithKey f g h (PTrie x) (PTrie y) =-    fmap-      PTrie-      (gmergeWithKey-         (\i ->-           gmergeWithKey-             (\j -> f (i:*:j))-             (g' i)-             (h' i))-         (coerce g)-         (coerce h)-         x-         y)-    where-    g' i t = do PTrie t' <- g (PTrie (gtrieSingleton i t))-                gtrieLookup i t'-    h' i t = do PTrie t' <- h (PTrie (gtrieSingleton i t))-                gtrieLookup i t'-  {-# INLINE gtrieLookup #-}-  {-# INLINE gtrieInsert #-}-  {-# INLINE gtrieDelete #-}-  {-# INLINE gtrieSingleton #-}-  {-# INLINE gtrieMap #-}-  {-# INLINE gtrieTraverse #-}-  {-# INLINE gfoldWithKey #-}-  {-# INLINE gtraverseWithKey #-}-  {-# INLINE gmergeWithKey #-}-  {-# INLINE gmapMaybeWithKey #-}+-- | 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) -instance (GTrieKeyShow f, GTrieKeyShow g) => GTrieKeyShow (f :*: g) where-  gtrieShowsPrec p (PTrie x)            = showsPrec p x+-- | Version of 'filter' where the predicate also gets the key.+filterWithKey :: TrieKey k => (k -> a -> Bool) -> Trie k a -> Trie k a+filterWithKey p = mapMaybeWithKey aux+  where+  aux k x+    | p k x     = Just x+    | otherwise = Nothing  ---------------------------------------------------------------------------------- Generic implementation for sums----------------------------------------------------------------------------------- | Generic sums are represented by up to a pair of sub-tries.-instance (GTrieKey f, GTrieKey g) => GTrieKey (f :+: g) where--  gtrieLookup (L1 k) (STrieL x)         = gtrieLookup k x-  gtrieLookup (L1 k) (STrieB x _)       = gtrieLookup k x-  gtrieLookup (R1 k) (STrieR y)         = gtrieLookup k y-  gtrieLookup (R1 k) (STrieB _ y)       = gtrieLookup k y-  gtrieLookup _      _                  = Nothing--  gtrieInsert (L1 k) v (STrieL x)       = STrieL (gtrieInsert k v x)-  gtrieInsert (L1 k) v (STrieR y)       = STrieB (gtrieSingleton k v) y-  gtrieInsert (L1 k) v (STrieB x y)     = STrieB (gtrieInsert k v x) y-  gtrieInsert (R1 k) v (STrieL x)       = STrieB x (gtrieSingleton k v)-  gtrieInsert (R1 k) v (STrieR y)       = STrieR (gtrieInsert k v y)-  gtrieInsert (R1 k) v (STrieB x y)     = STrieB x (gtrieInsert k v y)--  gtrieSingleton (L1 k) v               = STrieL (gtrieSingleton k v)-  gtrieSingleton (R1 k) v               = STrieR (gtrieSingleton k v)--  gtrieDelete (L1 k) (STrieL x)         = fmap STrieL (gtrieDelete k x)-  gtrieDelete (L1 _) (STrieR y)         = Just (STrieR y)-  gtrieDelete (L1 k) (STrieB x y)       = case gtrieDelete k x of-                                            Nothing -> Just (STrieR y)-                                            Just x' -> Just (STrieB x' y)-  gtrieDelete (R1 _) (STrieL x)         = Just (STrieL x)-  gtrieDelete (R1 k) (STrieR y)         = fmap STrieR (gtrieDelete k y)-  gtrieDelete (R1 k) (STrieB x y)       = case gtrieDelete k y of-                                            Nothing -> Just (STrieL x)-                                            Just y' -> Just (STrieB x y')--  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)--  gtrieTraverse f (STrieB x y)          = liftA2 STrieB (gtrieTraverse f x) (gtrieTraverse f y)-  gtrieTraverse f (STrieL x)            = fmap STrieL (gtrieTraverse f x)-  gtrieTraverse f (STrieR y)            = fmap STrieR (gtrieTraverse f y)--  gmapMaybeWithKey f (STrieL x)         = fmap STrieL (gmapMaybeWithKey (f . L1) x)-  gmapMaybeWithKey f (STrieR y)         = fmap STrieR (gmapMaybeWithKey (f . R1) y)-  gmapMaybeWithKey f (STrieB x y)       = case (gmapMaybeWithKey (f . L1) x, gmapMaybeWithKey (f . R1) y) of-                                            (Nothing, Nothing) -> Nothing-                                            (Just x', Nothing) -> Just (STrieL x')-                                            (Nothing, Just y') -> Just (STrieR y')-                                            (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--  gtraverseWithKey f (STrieL x)         = fmap STrieL (gtraverseWithKey (f . L1) x)-  gtraverseWithKey f (STrieR y)         = fmap STrieR (gtraverseWithKey (f . R1) y)-  gtraverseWithKey f (STrieB x y)       = liftA2 STrieB (gtraverseWithKey (f . L1) x)-                                                        (gtraverseWithKey (f . R1) y)--  gmergeWithKey f g h x0 y0 =-    case (split x0, split y0) of-      ((xl,xr),(yl,yr)) -> build (mergel xl yl) (merger xr yr)-    where-    split (STrieL x)   = (Just x, Nothing)-    split (STrieR y)   = (Nothing, Just y)-    split (STrieB x y) = (Just x, Just y)--    build (Just x) (Just y) = Just (STrieB x y)-    build (Just x) Nothing  = Just (STrieL x)-    build Nothing  (Just y) = Just (STrieR y)-    build Nothing  Nothing  = Nothing--    mergel Nothing  Nothing  = Nothing-    mergel (Just x) Nothing  = gl x-    mergel Nothing  (Just y) = hl y-    mergel (Just x) (Just y) = gmergeWithKey (f . L1) gl hl x y--    merger Nothing  Nothing  = Nothing-    merger (Just x) Nothing  = gr x-    merger Nothing  (Just y) = hr y-    merger (Just x) (Just y) = gmergeWithKey (f . R1) gr hr x y--    gl t = do STrieL t' <- g (STrieL t)-              return t'-    gr t = do STrieR t' <- g (STrieR t)-              return t'-    hl t = do STrieL t' <- h (STrieL t)-              return t'-    hr t = do STrieR t' <- h (STrieR t)-              return t'--  {-# INLINE gtrieLookup #-}-  {-# INLINE gtrieInsert #-}-  {-# INLINE gtrieDelete #-}-  {-# INLINE gtrieSingleton #-}-  {-# INLINE gtrieTraverse #-}-  {-# INLINE gtrieMap #-}-  {-# INLINE gfoldWithKey #-}-  {-# INLINE gtraverseWithKey #-}-  {-# INLINE gmergeWithKey #-}-  {-# INLINE gmapMaybeWithKey #-}--instance (GTrieKeyShow f, GTrieKeyShow g) => GTrieKeyShow (f :+: g) where-  gtrieShowsPrec p (STrieB x y)         = showParen (p > 10)-                                        $ showString "STrieB "-                                        . showsPrec 11 x-                                        . showString " "-                                        . showsPrec 11 y-  gtrieShowsPrec p (STrieL x)           = showParen (p > 10)-                                        $ showString "STrieL "-                                        . showsPrec 11 x-  gtrieShowsPrec p (STrieR y)           = showParen (p > 10)-                                        $ showString "STrieR "-                                        . showsPrec 11 y----------------------------------------------------------------------------------- Generic implementation for units----------------------------------------------------------------------------------- | Tries of constructors without fields are represented by a single value.-instance GTrieKey U1 where-  gtrieLookup _ (UTrie x)       = Just x-  gtrieInsert _ v _             = UTrie v-  gtrieDelete _ _               = Nothing-  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)-  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 gtrieSingleton #-}-  {-# INLINE gtrieTraverse #-}-  {-# INLINE gtrieMap #-}-  {-# INLINE gfoldWithKey #-}-  {-# INLINE gtraverseWithKey #-}-  {-# INLINE gmergeWithKey #-}-  {-# INLINE gmapMaybeWithKey #-}--instance GTrieKeyShow U1 where-  gtrieShowsPrec p (UTrie x)    = showsPrec p x----------------------------------------------------------------------------------- Generic implementation for empty types----------------------------------------------------------------------------------- | Tries of types without constructors are represented by a unit.-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"-  {-# INLINE gtrieLookup #-}-  {-# INLINE gtrieInsert #-}-  {-# INLINE gtrieDelete #-}-  {-# INLINE gtrieSingleton #-}-  {-# INLINE gtrieMap #-}-  {-# INLINE gtrieTraverse #-}-  {-# INLINE gfoldWithKey #-}-  {-# INLINE gtraverseWithKey #-}-  {-# INLINE gmergeWithKey #-}-  {-# INLINE gmapMaybeWithKey #-}+-- | Fold a trie with a function of the value+fold :: TrieKey k => (a -> r -> r) -> r -> Trie k a -> r+fold = trieFoldWithKey . const+{-# INLINE fold #-} -instance GTrieKeyShow V1 where-  gtrieShowsPrec _ _            = showString "()"+-- | Fold a trie with a function of both key and value+foldWithKey :: TrieKey k => (k -> a -> r -> r) -> r -> Trie k a -> r+foldWithKey = trieFoldWithKey+{-# INLINE foldWithKey #-} ---------------------------------------------------------------------------------- Various helpers-------------------------------------------------------------------------------+-- | Traverse a trie with a function of both key and value+traverseWithKey :: (TrieKey k, Applicative f) => (k -> a -> f b) -> Trie k a -> f (Trie k b)+traverseWithKey = trieTraverseWithKey+{-# INLINE traverseWithKey #-} --- | Construct a trie from a list of key/value pairs-fromList :: TrieKey k => [(k,v)] -> Trie k v-fromList = foldl' (\acc (k,v) -> insert k v acc) empty+mergeWithKey ::+  TrieKey k =>+  (k -> a -> b -> Maybe c) ->+  (Trie k a -> Trie k c) ->+  (Trie k b -> Trie k c) ->+  Trie k a -> Trie k b -> Trie k c+mergeWithKey = trieMergeWithKey+{-# INLINE mergeWithKey #-} --- | Alter the values of a trie. The function will take the value stored--- as the given key if one exists and should return a value to insert at--- that location or Nothing to delete from that location.+-- | Alter the value at the given key location.+-- The parameter function takes the value stored+-- 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 +-- | 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+-- first argument to the combining function.+insertWith :: TrieKey k => (v -> v -> v) -> k -> v -> Trie k v -> Trie k v+insertWith f k v = alter k $ \mb ->+                      case mb of+                        Just v0 -> Just (f v v0)+                        Nothing -> Just v++-- | Version of 'insertWith' that is strict in the result of combining+-- two elements.+insertWith' :: TrieKey k => (v -> v -> v) -> k -> v -> Trie k v -> Trie k v+insertWith' f k v = alter k $ \mb ->+                      case mb of+                        Just v0 -> Just $! f v v0+                        Nothing -> Just v+ -- | Returns 'True' when the 'Trie' has a value stored at the given key. member :: TrieKey k => k -> Trie k a -> Bool member k t = isJust (lookup k t)@@ -866,55 +219,50 @@ notMember :: TrieKey k => k -> Trie k a -> Bool notMember k t = isNothing (lookup k t) --- | Transform 'Trie' to an association list.+-- | 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 union = mergeWithKey (\_ a _ -> Just a) id id +-- | Union of two tries with function used to merge overlapping elements unionWith :: TrieKey k => (a -> a -> a) -> Trie k a -> Trie k a -> Trie k a unionWith f = mergeWithKey (\_ a b -> Just (f a b)) id id +-- | Union of two tries with function used to merge overlapping elements along with key unionWithKey :: TrieKey k => (k -> a -> a -> a) -> Trie k a -> Trie k a -> Trie k a unionWithKey f = mergeWithKey (\k a b -> Just (f k a b)) id id +-- | Left-biased intersection of two tries intersection :: TrieKey k => Trie k a -> Trie k b -> Trie k a intersection = mergeWithKey (\_ a _ -> Just a) (const empty) (const empty) +-- | Intersection of two tries parameterized by a combining function of the+-- values at overlapping keys intersectionWith :: TrieKey k => (a -> b -> c) -> Trie k a -> Trie k b -> Trie k c intersectionWith f = mergeWithKey (\_ a b -> Just (f a b)) (const empty) (const empty) +-- | Intersection of two tries parameterized by a combining function of the+-- key and the values at overlapping keys intersectionWithKey :: TrieKey k => (k -> a -> b -> c) -> Trie k a -> Trie k b -> Trie k c intersectionWithKey f = mergeWithKey (\k a b -> Just (f k a b)) (const empty) (const empty) +-- | Remove the keys of the right trie from the left trie difference :: TrieKey k => Trie k a -> Trie k b -> Trie k a difference = mergeWithKey (\_ _ _ -> Nothing) id (const empty) +-- | Parameterized 'difference' using a custom merge function.+-- Return 'Just' to change the value stored in left trie, or+-- 'Nothing' to remove from the left trie. differenceWith :: TrieKey k => (a -> b -> Maybe a) -> Trie k a -> Trie k b -> Trie k a differenceWith f = mergeWithKey (\_ -> f) id (const empty) +-- | 'differenceWith' where function also has access to the key differenceWithKey :: TrieKey k => (k -> a -> b -> Maybe a) -> Trie k a -> Trie k b -> Trie k a differenceWithKey f = mergeWithKey f id (const empty) +-- | Map a function over a trie filtering out elements where function returns 'Nothing' mapMaybe :: TrieKey k => (a -> Maybe b) -> Trie k a -> Trie k b mapMaybe f = mapMaybeWithKey (\_ -> f)----------------------------------------------------------------------------------- Various instances for Trie---------------------------------------------------------------------------------instance (Show a, TrieKey  k) => Show (Trie  k a) where-  showsPrec = trieShowsPrec--instance (Show a, GTrieKeyShow f) => Show (GTrie f a) where-  showsPrec = gtrieShowsPrec--instance TrieKey k => Functor (Trie k) where-  fmap = trieMap--instance TrieKey k => Foldable (Trie k) where-  foldr f = foldWithKey (\_ -> f)--instance TrieKey k => Traversable (Trie k) where-  traverse = trieTraverse
+ src/Data/GenericTrie/Internal.hs view
@@ -0,0 +1,902 @@+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE Trustworthy #-} -- coerce++-- | Unstable implementation details+module Data.GenericTrie.Internal+  ( TrieKey(..)+  , Trie(..)+  , OrdKey(..)+  -- * Generic derivation implementation+  , genericTrieNull+  , genericTrieMap+  , genericTrieTraverse+  , genericTrieShowsPrec+  , genericInsert+  , genericLookup+  , genericDelete+  , genericMapMaybeWithKey+  , genericSingleton+  , genericEmpty+  , genericAt+  , genericFoldWithKey+  , genericTraverseWithKey+  , TrieRepDefault+  , GTrieKey(..)+  , GTrie(..)+  ) where++import Control.Applicative (Applicative, liftA2)+import Data.Char (chr, ord)+import Data.Coerce (coerce)+import Data.Foldable (Foldable)+import Data.Functor.Compose (Compose(..))+import Data.IntMap (IntMap)+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.IntMap as IntMap+import qualified Data.Map as Map+import Prelude++-- | Types that may be used as the key of a 'Trie'.+--+-- For @data@ delcarations, the instance can be automatically derived from+-- a 'Generic' instance.+class TrieKey k where++  -- | Type of the representation of tries for this key.+  type TrieRep k :: * -> *++  -- | Construct an empty trie+  trieEmpty :: Trie k a++  -- | Test for an empty trie+  trieNull :: Trie k a -> Bool++  -- | Lookup element from trie+  trieLookup :: k -> Trie k a -> Maybe a++  -- | Insert element into trie+  trieInsert :: k -> a -> Trie k a -> Trie k a++  -- | Delete element from trie+  trieDelete :: k -> Trie k a -> Trie k a++  trieAt :: Functor f => k -> (Maybe a -> f (Maybe a)) ->+                              Trie k a -> f (Trie k a)++  -- | Construct a trie holding a single value+  trieSingleton :: k -> a -> Trie k a++  -- | Apply a function to all values stored in a trie+  trieMap :: (a -> b) -> Trie k a -> Trie k b++  -- | 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++  -- | Fold a trie with a function of both key and value.+  trieFoldWithKey :: (k -> a -> r -> r) -> r -> Trie k a -> r++  -- | 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)++  trieMergeWithKey :: (k -> a -> b -> Maybe c) ->+                      (Trie k a -> Trie k c) ->+                      (Trie k b -> Trie k c) ->+                      Trie k a -> Trie k b -> Trie k c+++  -- Defaults using 'Generic'++  type instance TrieRep k = TrieRepDefault k++  default trieEmpty :: ( TrieRep k ~ TrieRepDefault k) => Trie k a+  trieEmpty = genericEmpty++  default trieSingleton ::+    ( GTrieKey (Rep k), Generic k , TrieRep k ~ TrieRepDefault k) =>+    k -> a -> Trie k a+  trieSingleton = genericSingleton++  default trieNull ::+    ( TrieRep k ~ TrieRepDefault k) =>+    Trie k a -> Bool+  trieNull = genericTrieNull++  default trieLookup ::+    ( GTrieKey (Rep k), Generic k , TrieRep k ~ TrieRepDefault k) =>+    k -> Trie k a -> Maybe a+  trieLookup = genericLookup++  default trieInsert ::+    ( GTrieKey (Rep k), Generic k , TrieRep k ~ TrieRepDefault k) =>+    k -> a -> Trie k a -> Trie k a+  trieInsert = genericInsert++  default trieDelete ::+    ( GTrieKey (Rep k), Generic k , TrieRep k ~ TrieRepDefault k) =>+    k -> Trie k a -> Trie k a+  trieDelete = genericDelete++  default trieMap ::+    ( GTrieKey (Rep k) , TrieRep k ~ TrieRepDefault k) =>+    (a -> b) -> Trie k a -> Trie k b+  trieMap = genericTrieMap++  default trieTraverse ::+    ( GTrieKey (Rep k) , TrieRep k ~ TrieRepDefault k , Applicative f) =>+    (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+  trieMapMaybeWithKey = genericMapMaybeWithKey++  default trieFoldWithKey ::+    ( GTrieKey (Rep k) , TrieRep k ~ TrieRepDefault k, Generic k) =>+    (k -> a -> r -> r) -> r -> Trie k a -> r+  trieFoldWithKey = genericFoldWithKey++  default trieTraverseWithKey ::+    ( GTrieKey (Rep k) , TrieRep k ~ TrieRepDefault k, Generic k, Applicative f) =>+    (k -> a -> f b) -> Trie k a -> f (Trie k b)+  trieTraverseWithKey = genericTraverseWithKey++  default trieMergeWithKey ::+    ( GTrieKey (Rep k) , TrieRep k ~ TrieRepDefault k, Generic k ) =>+    (k -> a -> b -> Maybe c) ->+    (Trie k a -> Trie k c) ->+    (Trie k b -> Trie k c) ->+    Trie k a -> Trie k b -> Trie k c+  trieMergeWithKey = genericMergeWithKey++  default trieAt ::+    ( GTrieKey (Rep k) , TrieRep k ~ TrieRepDefault k, Generic k, Functor f ) =>+    k -> (Maybe a -> f (Maybe a)) -> Trie k a -> f (Trie k a)+  trieAt = genericAt++-- | The default implementation of a 'TrieRep' is 'GTrie' wrapped in+-- a 'Maybe'. This wrapping is due to the 'GTrie' being a non-empty+-- trie allowing all the of the "emptiness" to be represented at the+-- top level for any given generically implemented key.+type TrieRepDefault k = Compose Maybe (GTrie (Rep k))++-- | A map from keys of type @k@, to values of type @a@.+newtype Trie k a = MkTrie (TrieRep k a)+++------------------------------------------------------------------------------+-- Manually derived instances for base types+------------------------------------------------------------------------------++simpleAt ::+  (Functor f, TrieKey k) =>+  k -> (Maybe a -> f (Maybe a)) -> Trie k a -> f (Trie k a)+simpleAt k f m = flip fmap (f mv) $ \r -> case r of+    Nothing -> maybe m (const (trieDelete k m)) mv+    Just v' -> trieInsert k v' m+    where mv = trieLookup k m+{-# INLINE simpleAt #-}++-- | 'Int' tries are implemented with 'IntMap'.+instance TrieKey Int where+  type TrieRep Int              = IntMap+  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)+  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)+  trieFoldWithKey f z (MkTrie x)    = IntMap.foldWithKey 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)+  trieAt                        = simpleAt+  {-# INLINE trieEmpty #-}+  {-# INLINE trieInsert #-}+  {-# INLINE trieLookup #-}+  {-# INLINE trieDelete #-}+  {-# INLINE trieSingleton #-}+  {-# INLINE trieFoldWithKey #-}+  {-# INLINE trieShowsPrec #-}+  {-# INLINE trieTraverse #-}+  {-# INLINE trieTraverseWithKey #-}+  {-# INLINE trieNull #-}+  {-# INLINE trieMap #-}+  {-# INLINE trieMergeWithKey #-}+  {-# INLINE trieMapMaybeWithKey #-}++-- | '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)+  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)+  trieShowsPrec p (MkTrie x)        = showsPrec p x+  trieMapMaybeWithKey f (MkTrie x)  = MkTrie (Map.mapMaybeWithKey f x)+  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)+  trieAt                            = simpleAt+  {-# INLINE trieEmpty #-}+  {-# INLINE trieInsert #-}+  {-# INLINE trieLookup #-}+  {-# INLINE trieDelete #-}+  {-# INLINE trieSingleton #-}+  {-# INLINE trieFoldWithKey #-}+  {-# INLINE trieShowsPrec #-}+  {-# INLINE trieTraverse #-}+  {-# INLINE trieTraverseWithKey #-}+  {-# INLINE trieNull #-}+  {-# INLINE trieMap #-}+  {-# INLINE trieMergeWithKey #-}+  {-# INLINE trieMapMaybeWithKey #-}++-- | '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)+  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)+  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)+  trieAt                            = simpleAt+  {-# INLINE trieEmpty #-}+  {-# INLINE trieInsert #-}+  {-# INLINE trieLookup #-}+  {-# INLINE trieDelete #-}+  {-# INLINE trieSingleton #-}+  {-# INLINE trieFoldWithKey #-}+  {-# INLINE trieShowsPrec #-}+  {-# INLINE trieTraverse #-}+  {-# INLINE trieTraverseWithKey #-}+  {-# INLINE trieNull #-}+  {-# INLINE trieMap #-}+  {-# INLINE trieMergeWithKey #-}+  {-# INLINE trieMapMaybeWithKey #-}++-- | 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 }+  deriving (Read, Show, Eq, Ord)++-- | 'OrdKey' tries are implemented with 'Map', this is+-- 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+  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)+  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)+  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)+  trieAt                                = simpleAt+  {-# INLINE trieEmpty #-}+  {-# INLINE trieInsert #-}+  {-# INLINE trieLookup #-}+  {-# INLINE trieDelete #-}+  {-# INLINE trieSingleton #-}+  {-# INLINE trieFoldWithKey #-}+  {-# INLINE trieShowsPrec #-}+  {-# INLINE trieTraverse #-}+  {-# INLINE trieTraverseWithKey #-}+  {-# INLINE trieNull #-}+  {-# INLINE trieMap #-}+  {-# INLINE trieMergeWithKey #-}+  {-# INLINE trieMapMaybeWithKey #-}++------------------------------------------------------------------------------+-- Automatically derived instances for common types+------------------------------------------------------------------------------++instance                                      TrieKey ()+instance                                      TrieKey Bool+instance TrieKey k                         => TrieKey (Maybe k)+instance (TrieKey a, TrieKey b)            => TrieKey (Either a b)+instance (TrieKey a, TrieKey b)            => TrieKey (a,b)+instance (TrieKey a, TrieKey b, TrieKey c) => TrieKey (a,b,c)+instance (TrieKey a, TrieKey b, TrieKey c, TrieKey d) => TrieKey (a,b,c,d)+instance (TrieKey a, TrieKey b, TrieKey c, TrieKey d, TrieKey e) => TrieKey (a,b,c,d,e)+instance TrieKey k                         => TrieKey [k]++------------------------------------------------------------------------------+-- Generic 'TrieKey' method implementations+------------------------------------------------------------------------------++-- | Generic implementation of 'lookup'. This is the default implementation.+genericLookup ::+    ( GTrieKey (Rep k), Generic k+    , TrieRep k ~ TrieRepDefault k+    ) =>+    k -> Trie k a -> Maybe a+genericLookup k (MkTrie (Compose t)) = gtrieLookup (from k) =<< t+{-# INLINABLE genericLookup #-}++-- | Generic implementation of 'trieNull'. This is the default implementation.+genericTrieNull ::+    ( TrieRep k ~ TrieRepDefault k+    ) =>+    Trie k a -> Bool+genericTrieNull (MkTrie (Compose mb)) = isNothing mb+{-# INLINABLE genericTrieNull #-}++-- | Generic implementation of 'singleton'. This is the default implementation.+genericSingleton ::+    ( GTrieKey (Rep k), Generic k+    , TrieRep k ~ TrieRepDefault k+    ) =>+    k -> a -> Trie k a+genericSingleton k v = MkTrie $ Compose $ Just $! gtrieSingleton (from k) v+{-# INLINABLE genericSingleton #-}++-- | Generic implementation of 'empty'. This is the default implementation.+genericEmpty ::+    ( TrieRep k ~ TrieRepDefault k+    ) =>+    Trie k a+genericEmpty = MkTrie (Compose Nothing)+{-# INLINABLE genericEmpty #-}++-- | Generic implementation of 'insert'. This is the default implementation.+genericAt ::+    ( GTrieKey (Rep k), Generic k+    , TrieRep k ~ TrieRepDefault k+    , Functor f+    ) =>+    k -> (Maybe a -> f (Maybe a)) -> Trie k a -> f (Trie k a)+genericAt k f (MkTrie (Compose m)) =+  case m of+    Nothing -> fmap (MkTrie . Compose . fmap (gtrieSingleton (from k))) (f Nothing)+    Just t  -> gtrieAt (MkTrie . Compose) (from k) f t+{-# INLINABLE genericAt #-}++-- | Generic implementation of 'insert'. This is the default implementation.+genericInsert ::+    ( GTrieKey (Rep k), Generic k+    , TrieRep k ~ TrieRepDefault k+    ) =>+    k -> a -> Trie k a -> Trie k a+genericInsert k v (MkTrie (Compose m)) = MkTrie $ Compose $+  case m of+    Nothing -> Just $! gtrieSingleton (from k) v+    Just t  -> Just $! gtrieInsert    (from k) v t+{-# INLINABLE genericInsert #-}++-- | Generic implementation of 'delete'. This is the default implementation.+genericDelete ::+    ( GTrieKey (Rep k), Generic k+    , TrieRep k ~ TrieRepDefault k+    ) =>+    k -> Trie k a -> Trie k a+genericDelete k (MkTrie (Compose m)) = MkTrie (Compose (gtrieDelete (from k) =<< m))+{-# INLINABLE genericDelete #-}++-- | Generic implementation of 'trieMap'. This is the default implementation.+genericTrieMap ::+    ( GTrieKey (Rep k)+    , TrieRep k ~ TrieRepDefault k+    ) =>+    (a -> b) -> Trie k a -> Trie k b+genericTrieMap f (MkTrie (Compose x)) = MkTrie (Compose (fmap (gtrieMap f) $! x))+{-# INLINABLE genericTrieMap #-}+++-- | Generic implementation of 'trieTraverse'. This is the default implementation.+genericTrieTraverse ::+    ( GTrieKey (Rep k)+    , TrieRep k ~ TrieRepDefault k+    , Applicative f+    ) =>+    (a -> f b) -> Trie k a -> f (Trie k b)+genericTrieTraverse f (MkTrie (Compose x)) =+  fmap (MkTrie . Compose) (traverse (gtrieTraverse f) x)+{-# INLINABLE genericTrieTraverse #-}++-- | Generic implementation of 'trieShowsPrec'. This is the default implementation.+genericTrieShowsPrec ::+    ( Show a, GTrieKeyShow (Rep k)+    , TrieRep k ~ TrieRepDefault k+    ) =>+    Int -> Trie k a -> ShowS+genericTrieShowsPrec p (MkTrie (Compose m)) =+  case m of+    Just x  -> showsPrec p x+    Nothing -> showString "()"+{-# INLINABLE genericTrieShowsPrec #-}++-- | Generic implementation of 'mapMaybe'. This is the default implementation.+genericMapMaybeWithKey ::+    ( GTrieKey (Rep k), Generic k+    , TrieRep k ~ TrieRepDefault k+    ) =>+    (k -> a -> Maybe b) -> Trie k a -> Trie k b+genericMapMaybeWithKey f (MkTrie (Compose x)) = MkTrie (Compose (gmapMaybeWithKey (f . to) =<< x))+{-# INLINABLE genericMapMaybeWithKey #-}++-- | Generic implementation of 'foldWithKey'. This is the default implementation.+genericFoldWithKey ::+    ( GTrieKey (Rep k), Generic k+    , TrieRep k ~ TrieRepDefault k+    ) =>+    (k -> a -> r -> r) -> r -> Trie k a -> r+genericFoldWithKey f z (MkTrie (Compose m)) =+  case m of+    Nothing -> z+    Just x  -> gfoldWithKey (f . to) z x+{-# INLINABLE genericFoldWithKey #-}++-- | Generic implementation of 'traverseWithKey'. This is the default implementation.+genericTraverseWithKey ::+    ( GTrieKey (Rep k), Generic k+    , TrieRep k ~ TrieRepDefault k+    , Applicative f+    ) =>+    (k -> a -> f b) -> Trie k a -> f (Trie k b)+genericTraverseWithKey f (MkTrie (Compose m)) = fmap (MkTrie . Compose) (traverse (gtraverseWithKey (f . to)) m)+{-# INLINABLE genericTraverseWithKey #-}++-- | Generic implementation of 'mergeWithKey'. This is the default implementation.+genericMergeWithKey ::+    ( GTrieKey (Rep k), Generic k+    , TrieRep k ~ TrieRepDefault k+    ) =>+    (k -> a -> b -> Maybe c) -> (Trie k a -> Trie k c) -> (Trie k b -> Trie k c) ->+    Trie k a -> Trie k b -> Trie k c+genericMergeWithKey f g h (MkTrie (Compose x)) (MkTrie (Compose y)) =+  case (x,y) of+    (Nothing, Nothing) -> MkTrie (Compose Nothing)+    (Just{} , Nothing) -> g (MkTrie (Compose x))+    (Nothing, Just{} ) -> h (MkTrie (Compose y))+    (Just x', Just y') -> MkTrie (Compose (gmergeWithKey (f . to) (aux g) (aux h) x' y'))+      where+      aux k t = case k (MkTrie (Compose (Just t))) of+                  MkTrie (Compose r) -> r+{-# INLINABLE genericMergeWithKey #-}+++------------------------------------------------------------------------------+-- Generic implementation class+------------------------------------------------------------------------------++-- | Mapping of generic representation of keys to trie structures.+data    family   GTrie (f :: * -> *) a+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)+                                        | STrieB !(GTrie f a) !(GTrie g a)+newtype instance GTrie (f :*: g)  a     = PTrie (GTrie f (GTrie g a))+newtype instance GTrie (K1 i k)   a     = KTrie (Trie k a)+newtype instance GTrie U1         a     = UTrie a+data    instance GTrie V1         a++instance GTrieKey f => Functor (GTrie f) where+  fmap = gtrieMap++-- | TrieKey operations on Generic representations used to provide+-- the default implementations of tries.+class GTrieKey f where+  gtrieLookup    :: f p -> GTrie f a -> Maybe a+  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)+  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)+  gmergeWithKey  :: (f p -> a -> b -> Maybe c) ->+                    (GTrie f a -> Maybe (GTrie f c)) ->+                    (GTrie f b -> Maybe (GTrie f c)) ->+                    GTrie f a -> GTrie f b -> Maybe (GTrie f c)+  gtrieAt        :: Functor m =>+                      (Maybe (GTrie f a) -> r) ->+                      f p ->+                      (Maybe a -> m (Maybe a)) ->+                      GTrie f a -> m r++-- | The 'GTrieKeyShow' class provides generic implementations+-- of 'showsPrec'. This class is separate due to its implementation+-- varying for diferent kinds of metadata.+class GTrieKeyShow f where+  gtrieShowsPrec :: Show a => Int -> GTrie f a -> ShowS++------------------------------------------------------------------------------+-- Generic implementation for metadata+------------------------------------------------------------------------------++-- | Generic metadata is skipped in trie representation and operations.+instance GTrieKey f => GTrieKey (M1 i c f) where+  gtrieLookup (M1 k) (MTrie x)  = gtrieLookup k x+  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)+  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)+  gmergeWithKey f g h (MTrie x) (MTrie y) = fmap MTrie (gmergeWithKey (f . M1) (coerce g) (coerce h) x y)+  gtrieAt z (M1 k) f (MTrie x)  = gtrieAt (z . fmap MTrie) k f x+  {-# INLINE gtrieLookup #-}+  {-# INLINE gtrieInsert #-}+  {-# INLINE gtrieSingleton #-}+  {-# INLINE gtrieDelete #-}+  {-# INLINE gtrieMap #-}+  {-# INLINE gmapMaybeWithKey #-}+  {-# INLINE gtrieTraverse #-}+  {-# INLINE gfoldWithKey #-}+  {-# INLINE gtraverseWithKey #-}+  {-# INLINE gtrieAt #-}++data MProxy c (f :: * -> *) a = MProxy++instance GTrieKeyShow f => GTrieKeyShow (M1 D d f) where+  gtrieShowsPrec p (MTrie x)    = showsPrec p x+instance (Constructor c, GTrieKeyShow f) => GTrieKeyShow (M1 C c f) where+  gtrieShowsPrec p (MTrie x)    = showParen (p > 10)+                                $ showString "Con "+                                . shows (conName (MProxy :: MProxy c f ()))+                                . showString " "+                                . showsPrec 11 x+instance GTrieKeyShow f => GTrieKeyShow (M1 S s f) where+  gtrieShowsPrec p (MTrie x)    = showsPrec p x++------------------------------------------------------------------------------+-- Generic implementation for fields+------------------------------------------------------------------------------++checkNull :: TrieKey k => Trie k a -> Maybe (Trie k a)+checkNull x+  | trieNull x = Nothing+  | otherwise  = Just x++-- | Generic fields are represented by tries of the field type.+instance TrieKey k => GTrieKey (K1 i k) where+  gtrieLookup (K1 k) (KTrie x)          = trieLookup k x+  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))+  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)+  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+              Just (KTrie t') -> t'+              Nothing         -> trieEmpty+     h' t = case h (KTrie t) of+              Just (KTrie t') -> t'+              Nothing         -> trieEmpty+  gtrieAt z (K1 k) f (KTrie x) = fmap (z . fmap KTrie . checkNull) (trieAt k f x)+  {-# INLINE gtrieLookup #-}+  {-# INLINE gtrieInsert #-}+  {-# INLINE gtrieSingleton #-}+  {-# INLINE gtrieDelete #-}+  {-# INLINE gtrieMap #-}+  {-# INLINE gtrieTraverse #-}+  {-# INLINE gfoldWithKey #-}+  {-# INLINE gtraverseWithKey #-}+  {-# INLINE gmergeWithKey #-}+  {-# INLINE gmapMaybeWithKey #-}+  {-# INLINE gtrieAt #-}++instance TrieKey k => GTrieKeyShow (K1 i k) where+  gtrieShowsPrec p (KTrie x)            = showsPrec p x++------------------------------------------------------------------------------+-- Generic implementation for products+------------------------------------------------------------------------------++-- | Generic products are represented by tries of tries.+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))+  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)+  gmapMaybeWithKey f (PTrie x)          = fmap PTrie (gmapMaybeWithKey (\i -> gmapMaybeWithKey (\j -> f (i:*:j))) x)+  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)+  gmergeWithKey f g h (PTrie x) (PTrie y) =+    fmap+      PTrie+      (gmergeWithKey+         (\i ->+           gmergeWithKey+             (\j -> f (i:*:j))+             (g' i)+             (h' i))+         (coerce g)+         (coerce h)+         x+         y)+    where+    g' i t = do PTrie t' <- g (PTrie (gtrieSingleton i t))+                gtrieLookup i t'+    h' i t = do PTrie t' <- h (PTrie (gtrieSingleton i t))+                gtrieLookup i t'++  gtrieAt z (i :*: j) f (PTrie t) = gtrieAt (z . fmap PTrie) i f1 t+    where+    f1 Nothing = fmap (fmap (gtrieSingleton j)) (f Nothing)+    f1 (Just ti) = gtrieAt id j f ti+++  {-# INLINE gtrieLookup #-}+  {-# INLINE gtrieInsert #-}+  {-# INLINE gtrieDelete #-}+  {-# INLINE gtrieSingleton #-}+  {-# INLINE gtrieMap #-}+  {-# INLINE gtrieTraverse #-}+  {-# INLINE gfoldWithKey #-}+  {-# INLINE gtraverseWithKey #-}+  {-# INLINE gmergeWithKey #-}+  {-# INLINE gmapMaybeWithKey #-}+  {-# INLINE gtrieAt #-}++instance (GTrieKeyShow f, GTrieKeyShow g) => GTrieKeyShow (f :*: g) where+  gtrieShowsPrec p (PTrie x)            = showsPrec p x+++------------------------------------------------------------------------------+-- Generic implementation for sums+------------------------------------------------------------------------------++-- | Generic sums are represented by up to a pair of sub-tries.+instance (GTrieKey f, GTrieKey g) => GTrieKey (f :+: g) where++  gtrieLookup (L1 k) (STrieL x)         = gtrieLookup k x+  gtrieLookup (L1 k) (STrieB x _)       = gtrieLookup k x+  gtrieLookup (R1 k) (STrieR y)         = gtrieLookup k y+  gtrieLookup (R1 k) (STrieB _ y)       = gtrieLookup k y+  gtrieLookup _      _                  = Nothing++  gtrieInsert (L1 k) v (STrieL x)       = STrieL (gtrieInsert k v x)+  gtrieInsert (L1 k) v (STrieR y)       = STrieB (gtrieSingleton k v) y+  gtrieInsert (L1 k) v (STrieB x y)     = STrieB (gtrieInsert k v x) y+  gtrieInsert (R1 k) v (STrieL x)       = STrieB x (gtrieSingleton k v)+  gtrieInsert (R1 k) v (STrieR y)       = STrieR (gtrieInsert k v y)+  gtrieInsert (R1 k) v (STrieB x y)     = STrieB x (gtrieInsert k v y)++  gtrieSingleton (L1 k) v               = STrieL (gtrieSingleton k v)+  gtrieSingleton (R1 k) v               = STrieR (gtrieSingleton k v)++  gtrieDelete (L1 k) (STrieL x)         = fmap STrieL (gtrieDelete k x)+  gtrieDelete (L1 _) (STrieR y)         = Just (STrieR y)+  gtrieDelete (L1 k) (STrieB x y)       = case gtrieDelete k x of+                                            Nothing -> Just (STrieR y)+                                            Just x' -> Just (STrieB x' y)+  gtrieDelete (R1 _) (STrieL x)         = Just (STrieL x)+  gtrieDelete (R1 k) (STrieR y)         = fmap STrieR (gtrieDelete k y)+  gtrieDelete (R1 k) (STrieB x y)       = case gtrieDelete k y of+                                            Nothing -> Just (STrieL x)+                                            Just y' -> Just (STrieB x y')++  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)++  gtrieTraverse f (STrieB x y)          = liftA2 STrieB (gtrieTraverse f x) (gtrieTraverse f y)+  gtrieTraverse f (STrieL x)            = fmap STrieL (gtrieTraverse f x)+  gtrieTraverse f (STrieR y)            = fmap STrieR (gtrieTraverse f y)++  gmapMaybeWithKey f (STrieL x)         = fmap STrieL (gmapMaybeWithKey (f . L1) x)+  gmapMaybeWithKey f (STrieR y)         = fmap STrieR (gmapMaybeWithKey (f . R1) y)+  gmapMaybeWithKey f (STrieB x y)       = case (gmapMaybeWithKey (f . L1) x, gmapMaybeWithKey (f . R1) y) of+                                            (Nothing, Nothing) -> Nothing+                                            (Just x', Nothing) -> Just (STrieL x')+                                            (Nothing, Just y') -> Just (STrieR y')+                                            (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++  gtraverseWithKey f (STrieL x)         = fmap STrieL (gtraverseWithKey (f . L1) x)+  gtraverseWithKey f (STrieR y)         = fmap STrieR (gtraverseWithKey (f . R1) y)+  gtraverseWithKey f (STrieB x y)       = liftA2 STrieB (gtraverseWithKey (f . L1) x)+                                                        (gtraverseWithKey (f . R1) y)++  gmergeWithKey f g h x0 y0 =+    case (split x0, split y0) of+      ((xl,xr),(yl,yr)) -> build (mergel xl yl) (merger xr yr)+    where+    split (STrieL x)   = (Just x, Nothing)+    split (STrieR y)   = (Nothing, Just y)+    split (STrieB x y) = (Just x, Just y)++    build (Just x) (Just y) = Just (STrieB x y)+    build (Just x) Nothing  = Just (STrieL x)+    build Nothing  (Just y) = Just (STrieR y)+    build Nothing  Nothing  = Nothing++    mergel Nothing  Nothing  = Nothing+    mergel (Just x) Nothing  = gl x+    mergel Nothing  (Just y) = hl y+    mergel (Just x) (Just y) = gmergeWithKey (f . L1) gl hl x y++    merger Nothing  Nothing  = Nothing+    merger (Just x) Nothing  = gr x+    merger Nothing  (Just y) = hr y+    merger (Just x) (Just y) = gmergeWithKey (f . R1) gr hr x y++    gl t = do STrieL t' <- g (STrieL t)+              return t'+    gr t = do STrieR t' <- g (STrieR t)+              return t'+    hl t = do STrieL t' <- h (STrieL t)+              return t'+    hr t = do STrieR t' <- h (STrieR t)+              return t'++  gtrieAt z (L1 k) f (STrieL x)   = gtrieAt (z . fmap STrieL) k f x+  gtrieAt z (R1 k) f (STrieR y)   = gtrieAt (z . fmap STrieR) k f y+  gtrieAt z (L1 k) f (STrieR y)   = fmap (z . Just . maybe (STrieR y) (\v -> STrieB (gtrieSingleton k v) y)) (f Nothing)+  gtrieAt z (R1 k) f (STrieL x)   = fmap (z . Just . maybe (STrieL x) (\v -> STrieB x (gtrieSingleton k v))) (f Nothing)+  gtrieAt z (L1 k) f (STrieB x y) = gtrieAt (z . Just . maybe (STrieR y) (`STrieB` y)) k f x+  gtrieAt z (R1 k) f (STrieB x y) = gtrieAt (z . Just . maybe (STrieL x) (x `STrieB`)) k f y++  {-# INLINE gtrieLookup #-}+  {-# INLINE gtrieInsert #-}+  {-# INLINE gtrieDelete #-}+  {-# INLINE gtrieSingleton #-}+  {-# INLINE gtrieTraverse #-}+  {-# INLINE gtrieMap #-}+  {-# INLINE gfoldWithKey #-}+  {-# INLINE gtraverseWithKey #-}+  {-# INLINE gmergeWithKey #-}+  {-# INLINE gmapMaybeWithKey #-}+  {-# INLINE gtrieAt #-}++instance (GTrieKeyShow f, GTrieKeyShow g) => GTrieKeyShow (f :+: g) where+  gtrieShowsPrec p (STrieB x y)         = showParen (p > 10)+                                        $ showString "STrieB "+                                        . showsPrec 11 x+                                        . showString " "+                                        . showsPrec 11 y+  gtrieShowsPrec p (STrieL x)           = showParen (p > 10)+                                        $ showString "STrieL "+                                        . showsPrec 11 x+  gtrieShowsPrec p (STrieR y)           = showParen (p > 10)+                                        $ showString "STrieR "+                                        . showsPrec 11 y++------------------------------------------------------------------------------+-- Generic implementation for units+------------------------------------------------------------------------------++-- | Tries of constructors without fields are represented by a single value.+instance GTrieKey U1 where+  gtrieLookup _ (UTrie x)       = Just x+  gtrieInsert _ v _             = UTrie v+  gtrieDelete _ _               = Nothing+  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)+  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)+  gtrieAt z _ f (UTrie x)       = fmap (z . fmap UTrie) (f (Just x))+  {-# INLINE gtrieLookup #-}+  {-# INLINE gtrieInsert #-}+  {-# INLINE gtrieDelete #-}+  {-# INLINE gtrieSingleton #-}+  {-# INLINE gtrieTraverse #-}+  {-# INLINE gtrieMap #-}+  {-# INLINE gfoldWithKey #-}+  {-# INLINE gtraverseWithKey #-}+  {-# INLINE gmergeWithKey #-}+  {-# INLINE gmapMaybeWithKey #-}+  {-# INLINE gtrieAt #-}++instance GTrieKeyShow U1 where+  gtrieShowsPrec p (UTrie x)    = showsPrec p x++------------------------------------------------------------------------------+-- Generic implementation for empty types+------------------------------------------------------------------------------++-- | Tries of types without constructors are represented by a unit.+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"+  gtrieAt _ k _ t               = k `seq` t `seq` error "GTrieKey.V1: gtrieAt"+  {-# INLINE gtrieLookup #-}+  {-# INLINE gtrieInsert #-}+  {-# INLINE gtrieDelete #-}+  {-# INLINE gtrieSingleton #-}+  {-# INLINE gtrieMap #-}+  {-# INLINE gtrieTraverse #-}+  {-# INLINE gfoldWithKey #-}+  {-# INLINE gtraverseWithKey #-}+  {-# INLINE gmergeWithKey #-}+  {-# INLINE gmapMaybeWithKey #-}+  {-# INLINE gtrieAt #-}++instance GTrieKeyShow V1 where+  gtrieShowsPrec _ _            = showString "()"+++------------------------------------------------------------------------------+-- Various instances for Trie+------------------------------------------------------------------------------++instance (Show a, TrieKey  k) => Show (Trie  k a) where+  showsPrec = trieShowsPrec++instance (Show a, GTrieKeyShow f) => Show (GTrie f a) where+  showsPrec = gtrieShowsPrec++instance TrieKey k => Functor (Trie k) where+  fmap = trieMap++instance TrieKey k => Foldable (Trie k) where+  foldr f = trieFoldWithKey (\_ -> f)++instance TrieKey k => Traversable (Trie k) where+  traverse = trieTraverse