packages feed

ghc 9.8.3 → 9.8.4

raw patch · 71 files changed

+8121/−523 lines, 71 filesdep ~ghc-bootdep ~ghc-heapdep ~ghciPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: ghc-boot, ghc-heap, ghci

API changes (from Hackage documentation)

- GHC.CmmToAsm.CFG.Dominators: asGraph :: Tree Node -> Rooted
- GHC.Core.Opt.Monad: getUniqMask :: CoreM Char
- GHC.Driver.CmdLine: WordSuffix :: (Word -> EwM m ()) -> OptKind (m :: Type -> Type)
- GHC.Tc.Types: [env_um] :: Env gbl lcl -> {-# UNPACK #-} !Char
- GHC.Types.Unique.Supply: uniqFromMask :: Char -> IO Unique
- GHC.Utils.Outputable: instance GHC.Utils.Outputable.Outputable Data.IntSet.Internal.IntSet
+ GHC: [modBreaks_module] :: ModBreaks -> RemotePtr ModuleName
+ GHC.ByteCode.Types: [modBreaks_module] :: ModBreaks -> RemotePtr ModuleName
+ GHC.CmmToAsm.CFG.Dominators: asCGraph :: Tree Node -> Rooted
+ GHC.Core.Opt.Monad: getUniqTag :: CoreM Char
+ GHC.Data.Word64Map.Internal: (!) :: Word64Map a -> Key -> a
+ GHC.Data.Word64Map.Internal: (!?) :: Word64Map a -> Key -> Maybe a
+ GHC.Data.Word64Map.Internal: (\\) :: Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Internal: Bin :: {-# UNPACK #-} !Prefix -> {-# UNPACK #-} !Mask -> !Word64Map a -> !Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: Nil :: Word64Map a
+ GHC.Data.Word64Map.Internal: Tip :: {-# UNPACK #-} !Key -> a -> Word64Map a
+ GHC.Data.Word64Map.Internal: WhenMatched :: (Key -> x -> y -> f (Maybe z)) -> WhenMatched (f :: Type -> Type) x y z
+ GHC.Data.Word64Map.Internal: WhenMissing :: (Word64Map x -> f (Word64Map y)) -> (Key -> x -> f (Maybe y)) -> WhenMissing (f :: Type -> Type) x y
+ GHC.Data.Word64Map.Internal: [matchedKey] :: WhenMatched (f :: Type -> Type) x y z -> Key -> x -> y -> f (Maybe z)
+ GHC.Data.Word64Map.Internal: [missingKey] :: WhenMissing (f :: Type -> Type) x y -> Key -> x -> f (Maybe y)
+ GHC.Data.Word64Map.Internal: [missingSubtree] :: WhenMissing (f :: Type -> Type) x y -> Word64Map x -> f (Word64Map y)
+ GHC.Data.Word64Map.Internal: adjust :: (a -> a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: adjustWithKey :: (Key -> a -> a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: alter :: (Maybe a -> Maybe a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: alterF :: Functor f => (Maybe a -> f (Maybe a)) -> Key -> Word64Map a -> f (Word64Map a)
+ GHC.Data.Word64Map.Internal: assocs :: Word64Map a -> [(Key, a)]
+ GHC.Data.Word64Map.Internal: bin :: Prefix -> Mask -> Word64Map a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: binCheckLeft :: Prefix -> Mask -> Word64Map a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: binCheckRight :: Prefix -> Mask -> Word64Map a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: branchMask :: Prefix -> Prefix -> Mask
+ GHC.Data.Word64Map.Internal: compose :: Word64Map c -> Word64Map Word64 -> Word64Map c
+ GHC.Data.Word64Map.Internal: contramapFirstWhenMatched :: forall b a (f :: Type -> Type) y z. (b -> a) -> WhenMatched f a y z -> WhenMatched f b y z
+ GHC.Data.Word64Map.Internal: contramapSecondWhenMatched :: forall b a (f :: Type -> Type) x z. (b -> a) -> WhenMatched f x a z -> WhenMatched f x b z
+ GHC.Data.Word64Map.Internal: data WhenMissing (f :: Type -> Type) x y
+ GHC.Data.Word64Map.Internal: data Word64Map a
+ GHC.Data.Word64Map.Internal: delete :: Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: deleteFindMax :: Word64Map a -> ((Key, a), Word64Map a)
+ GHC.Data.Word64Map.Internal: deleteFindMin :: Word64Map a -> ((Key, a), Word64Map a)
+ GHC.Data.Word64Map.Internal: deleteMax :: Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: deleteMin :: Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: difference :: Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Internal: differenceWith :: (a -> b -> Maybe a) -> Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Internal: differenceWithKey :: (Key -> a -> b -> Maybe a) -> Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Internal: disjoint :: Word64Map a -> Word64Map b -> Bool
+ GHC.Data.Word64Map.Internal: dropMissing :: forall (f :: Type -> Type) x y. Applicative f => WhenMissing f x y
+ GHC.Data.Word64Map.Internal: dropWhileAntitone :: (Key -> Bool) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: elems :: Word64Map a -> [a]
+ GHC.Data.Word64Map.Internal: empty :: Word64Map a
+ GHC.Data.Word64Map.Internal: filter :: (a -> Bool) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: filterAMissing :: Applicative f => (Key -> x -> f Bool) -> WhenMissing f x x
+ GHC.Data.Word64Map.Internal: filterMissing :: forall (f :: Type -> Type) x. Applicative f => (Key -> x -> Bool) -> WhenMissing f x x
+ GHC.Data.Word64Map.Internal: filterWithKey :: (Key -> a -> Bool) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: findMax :: Word64Map a -> (Key, a)
+ GHC.Data.Word64Map.Internal: findMin :: Word64Map a -> (Key, a)
+ GHC.Data.Word64Map.Internal: findWithDefault :: a -> Key -> Word64Map a -> a
+ GHC.Data.Word64Map.Internal: foldMapWithKey :: Monoid m => (Key -> a -> m) -> Word64Map a -> m
+ GHC.Data.Word64Map.Internal: foldl :: (a -> b -> a) -> a -> Word64Map b -> a
+ GHC.Data.Word64Map.Internal: foldl' :: (a -> b -> a) -> a -> Word64Map b -> a
+ GHC.Data.Word64Map.Internal: foldlWithKey :: (a -> Key -> b -> a) -> a -> Word64Map b -> a
+ GHC.Data.Word64Map.Internal: foldlWithKey' :: (a -> Key -> b -> a) -> a -> Word64Map b -> a
+ GHC.Data.Word64Map.Internal: foldr :: (a -> b -> b) -> b -> Word64Map a -> b
+ GHC.Data.Word64Map.Internal: foldr' :: (a -> b -> b) -> b -> Word64Map a -> b
+ GHC.Data.Word64Map.Internal: foldrWithKey :: (Key -> a -> b -> b) -> b -> Word64Map a -> b
+ GHC.Data.Word64Map.Internal: foldrWithKey' :: (Key -> a -> b -> b) -> b -> Word64Map a -> b
+ GHC.Data.Word64Map.Internal: fromAscList :: [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Internal: fromAscListWith :: (a -> a -> a) -> [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Internal: fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Internal: fromDistinctAscList :: [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Internal: fromList :: [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Internal: fromListWith :: (a -> a -> a) -> [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Internal: fromListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Internal: fromSet :: (Key -> a) -> Word64Set -> Word64Map a
+ GHC.Data.Word64Map.Internal: highestBitMask :: Word64 -> Word64
+ GHC.Data.Word64Map.Internal: infixl 9 \\
+ GHC.Data.Word64Map.Internal: insert :: Key -> a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> Word64Map a -> (Maybe a, Word64Map a)
+ GHC.Data.Word64Map.Internal: insertWith :: (a -> a -> a) -> Key -> a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: instance (GHC.Base.Applicative f, GHC.Base.Monad f) => Control.Category.Category (GHC.Data.Word64Map.Internal.WhenMissing f)
+ GHC.Data.Word64Map.Internal: instance (GHC.Base.Applicative f, GHC.Base.Monad f) => GHC.Base.Applicative (GHC.Data.Word64Map.Internal.WhenMissing f x)
+ GHC.Data.Word64Map.Internal: instance (GHC.Base.Applicative f, GHC.Base.Monad f) => GHC.Base.Functor (GHC.Data.Word64Map.Internal.WhenMissing f x)
+ GHC.Data.Word64Map.Internal: instance (GHC.Base.Applicative f, GHC.Base.Monad f) => GHC.Base.Monad (GHC.Data.Word64Map.Internal.WhenMissing f x)
+ GHC.Data.Word64Map.Internal: instance (GHC.Base.Monad f, GHC.Base.Applicative f) => Control.Category.Category (GHC.Data.Word64Map.Internal.WhenMatched f x)
+ GHC.Data.Word64Map.Internal: instance (GHC.Base.Monad f, GHC.Base.Applicative f) => GHC.Base.Applicative (GHC.Data.Word64Map.Internal.WhenMatched f x y)
+ GHC.Data.Word64Map.Internal: instance (GHC.Base.Monad f, GHC.Base.Applicative f) => GHC.Base.Monad (GHC.Data.Word64Map.Internal.WhenMatched f x y)
+ GHC.Data.Word64Map.Internal: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (GHC.Data.Word64Map.Internal.Word64Map a)
+ GHC.Data.Word64Map.Internal: instance Data.Data.Data a => Data.Data.Data (GHC.Data.Word64Map.Internal.Word64Map a)
+ GHC.Data.Word64Map.Internal: instance Data.Foldable.Foldable GHC.Data.Word64Map.Internal.Word64Map
+ GHC.Data.Word64Map.Internal: instance Data.Functor.Classes.Eq1 GHC.Data.Word64Map.Internal.Word64Map
+ GHC.Data.Word64Map.Internal: instance Data.Functor.Classes.Ord1 GHC.Data.Word64Map.Internal.Word64Map
+ GHC.Data.Word64Map.Internal: instance Data.Functor.Classes.Read1 GHC.Data.Word64Map.Internal.Word64Map
+ GHC.Data.Word64Map.Internal: instance Data.Functor.Classes.Show1 GHC.Data.Word64Map.Internal.Word64Map
+ GHC.Data.Word64Map.Internal: instance Data.Traversable.Traversable GHC.Data.Word64Map.Internal.Word64Map
+ GHC.Data.Word64Map.Internal: instance GHC.Base.Functor GHC.Data.Word64Map.Internal.Word64Map
+ GHC.Data.Word64Map.Internal: instance GHC.Base.Functor f => GHC.Base.Functor (GHC.Data.Word64Map.Internal.WhenMatched f x y)
+ GHC.Data.Word64Map.Internal: instance GHC.Base.Monoid (GHC.Data.Word64Map.Internal.Word64Map a)
+ GHC.Data.Word64Map.Internal: instance GHC.Base.Semigroup (GHC.Data.Word64Map.Internal.Word64Map a)
+ GHC.Data.Word64Map.Internal: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Data.Word64Map.Internal.Word64Map a)
+ GHC.Data.Word64Map.Internal: instance GHC.Classes.Ord a => GHC.Classes.Ord (GHC.Data.Word64Map.Internal.Word64Map a)
+ GHC.Data.Word64Map.Internal: instance GHC.IsList.IsList (GHC.Data.Word64Map.Internal.Word64Map a)
+ GHC.Data.Word64Map.Internal: instance GHC.Read.Read e => GHC.Read.Read (GHC.Data.Word64Map.Internal.Word64Map e)
+ GHC.Data.Word64Map.Internal: instance GHC.Show.Show a => GHC.Show.Show (GHC.Data.Word64Map.Internal.Word64Map a)
+ GHC.Data.Word64Map.Internal: intFromNat :: Nat -> Key
+ GHC.Data.Word64Map.Internal: intersection :: Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Internal: intersectionWith :: (a -> b -> c) -> Word64Map a -> Word64Map b -> Word64Map c
+ GHC.Data.Word64Map.Internal: intersectionWithKey :: (Key -> a -> b -> c) -> Word64Map a -> Word64Map b -> Word64Map c
+ GHC.Data.Word64Map.Internal: isProperSubmapOf :: Eq a => Word64Map a -> Word64Map a -> Bool
+ GHC.Data.Word64Map.Internal: isProperSubmapOfBy :: (a -> b -> Bool) -> Word64Map a -> Word64Map b -> Bool
+ GHC.Data.Word64Map.Internal: isSubmapOf :: Eq a => Word64Map a -> Word64Map a -> Bool
+ GHC.Data.Word64Map.Internal: isSubmapOfBy :: (a -> b -> Bool) -> Word64Map a -> Word64Map b -> Bool
+ GHC.Data.Word64Map.Internal: keys :: Word64Map a -> [Key]
+ GHC.Data.Word64Map.Internal: keysSet :: Word64Map a -> Word64Set
+ GHC.Data.Word64Map.Internal: link :: Prefix -> Word64Map a -> Prefix -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: linkWithMask :: Mask -> Prefix -> Word64Map a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: lmapWhenMissing :: forall b a (f :: Type -> Type) x. (b -> a) -> WhenMissing f a x -> WhenMissing f b x
+ GHC.Data.Word64Map.Internal: lookup :: Key -> Word64Map a -> Maybe a
+ GHC.Data.Word64Map.Internal: lookupGE :: Key -> Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Internal: lookupGT :: Key -> Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Internal: lookupLE :: Key -> Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Internal: lookupLT :: Key -> Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Internal: lookupMax :: Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Internal: lookupMin :: Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Internal: map :: (a -> b) -> Word64Map a -> Word64Map b
+ GHC.Data.Word64Map.Internal: mapAccum :: (a -> b -> (a, c)) -> a -> Word64Map b -> (a, Word64Map c)
+ GHC.Data.Word64Map.Internal: mapAccumRWithKey :: (a -> Key -> b -> (a, c)) -> a -> Word64Map b -> (a, Word64Map c)
+ GHC.Data.Word64Map.Internal: mapAccumWithKey :: (a -> Key -> b -> (a, c)) -> a -> Word64Map b -> (a, Word64Map c)
+ GHC.Data.Word64Map.Internal: mapEither :: (a -> Either b c) -> Word64Map a -> (Word64Map b, Word64Map c)
+ GHC.Data.Word64Map.Internal: mapEitherWithKey :: (Key -> a -> Either b c) -> Word64Map a -> (Word64Map b, Word64Map c)
+ GHC.Data.Word64Map.Internal: mapGentlyWhenMatched :: forall (f :: Type -> Type) a b x y. Functor f => (a -> b) -> WhenMatched f x y a -> WhenMatched f x y b
+ GHC.Data.Word64Map.Internal: mapGentlyWhenMissing :: forall (f :: Type -> Type) a b x. Functor f => (a -> b) -> WhenMissing f x a -> WhenMissing f x b
+ GHC.Data.Word64Map.Internal: mapKeys :: (Key -> Key) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: mapKeysMonotonic :: (Key -> Key) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: mapKeysWith :: (a -> a -> a) -> (Key -> Key) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: mapMaybe :: (a -> Maybe b) -> Word64Map a -> Word64Map b
+ GHC.Data.Word64Map.Internal: mapMaybeMissing :: forall (f :: Type -> Type) x y. Applicative f => (Key -> x -> Maybe y) -> WhenMissing f x y
+ GHC.Data.Word64Map.Internal: mapMaybeWithKey :: (Key -> a -> Maybe b) -> Word64Map a -> Word64Map b
+ GHC.Data.Word64Map.Internal: mapMissing :: forall (f :: Type -> Type) x y. Applicative f => (Key -> x -> y) -> WhenMissing f x y
+ GHC.Data.Word64Map.Internal: mapWhenMatched :: forall (f :: Type -> Type) a b x y. Functor f => (a -> b) -> WhenMatched f x y a -> WhenMatched f x y b
+ GHC.Data.Word64Map.Internal: mapWhenMissing :: forall (f :: Type -> Type) a b x. (Applicative f, Monad f) => (a -> b) -> WhenMissing f x a -> WhenMissing f x b
+ GHC.Data.Word64Map.Internal: mapWithKey :: (Key -> a -> b) -> Word64Map a -> Word64Map b
+ GHC.Data.Word64Map.Internal: mask :: Key -> Mask -> Prefix
+ GHC.Data.Word64Map.Internal: maskW :: Nat -> Nat -> Prefix
+ GHC.Data.Word64Map.Internal: match :: Key -> Prefix -> Mask -> Bool
+ GHC.Data.Word64Map.Internal: maxView :: Word64Map a -> Maybe (a, Word64Map a)
+ GHC.Data.Word64Map.Internal: maxViewWithKey :: Word64Map a -> Maybe ((Key, a), Word64Map a)
+ GHC.Data.Word64Map.Internal: member :: Key -> Word64Map a -> Bool
+ GHC.Data.Word64Map.Internal: merge :: SimpleWhenMissing a c -> SimpleWhenMissing b c -> SimpleWhenMatched a b c -> Word64Map a -> Word64Map b -> Word64Map c
+ GHC.Data.Word64Map.Internal: mergeA :: Applicative f => WhenMissing f a c -> WhenMissing f b c -> WhenMatched f a b c -> Word64Map a -> Word64Map b -> f (Word64Map c)
+ GHC.Data.Word64Map.Internal: mergeWithKey :: (Key -> a -> b -> Maybe c) -> (Word64Map a -> Word64Map c) -> (Word64Map b -> Word64Map c) -> Word64Map a -> Word64Map b -> Word64Map c
+ GHC.Data.Word64Map.Internal: mergeWithKey' :: (Prefix -> Mask -> Word64Map c -> Word64Map c -> Word64Map c) -> (Word64Map a -> Word64Map b -> Word64Map c) -> (Word64Map a -> Word64Map c) -> (Word64Map b -> Word64Map c) -> Word64Map a -> Word64Map b -> Word64Map c
+ GHC.Data.Word64Map.Internal: minView :: Word64Map a -> Maybe (a, Word64Map a)
+ GHC.Data.Word64Map.Internal: minViewWithKey :: Word64Map a -> Maybe ((Key, a), Word64Map a)
+ GHC.Data.Word64Map.Internal: natFromInt :: Key -> Nat
+ GHC.Data.Word64Map.Internal: newtype WhenMatched (f :: Type -> Type) x y z
+ GHC.Data.Word64Map.Internal: nomatch :: Key -> Prefix -> Mask -> Bool
+ GHC.Data.Word64Map.Internal: notMember :: Key -> Word64Map a -> Bool
+ GHC.Data.Word64Map.Internal: null :: Word64Map a -> Bool
+ GHC.Data.Word64Map.Internal: partition :: (a -> Bool) -> Word64Map a -> (Word64Map a, Word64Map a)
+ GHC.Data.Word64Map.Internal: partitionWithKey :: (Key -> a -> Bool) -> Word64Map a -> (Word64Map a, Word64Map a)
+ GHC.Data.Word64Map.Internal: preserveMissing :: forall (f :: Type -> Type) x. Applicative f => WhenMissing f x x
+ GHC.Data.Word64Map.Internal: restrictKeys :: Word64Map a -> Word64Set -> Word64Map a
+ GHC.Data.Word64Map.Internal: runWhenMatched :: WhenMatched f x y z -> Key -> x -> y -> f (Maybe z)
+ GHC.Data.Word64Map.Internal: runWhenMissing :: WhenMissing f x y -> Key -> x -> f (Maybe y)
+ GHC.Data.Word64Map.Internal: shorter :: Mask -> Mask -> Bool
+ GHC.Data.Word64Map.Internal: showTree :: Show a => Word64Map a -> String
+ GHC.Data.Word64Map.Internal: showTreeWith :: Show a => Bool -> Bool -> Word64Map a -> String
+ GHC.Data.Word64Map.Internal: singleton :: Key -> a -> Word64Map a
+ GHC.Data.Word64Map.Internal: size :: Word64Map a -> Int
+ GHC.Data.Word64Map.Internal: spanAntitone :: (Key -> Bool) -> Word64Map a -> (Word64Map a, Word64Map a)
+ GHC.Data.Word64Map.Internal: split :: Key -> Word64Map a -> (Word64Map a, Word64Map a)
+ GHC.Data.Word64Map.Internal: splitLookup :: Key -> Word64Map a -> (Word64Map a, Maybe a, Word64Map a)
+ GHC.Data.Word64Map.Internal: splitRoot :: Word64Map a -> [Word64Map a]
+ GHC.Data.Word64Map.Internal: takeWhileAntitone :: (Key -> Bool) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: toAscList :: Word64Map a -> [(Key, a)]
+ GHC.Data.Word64Map.Internal: toDescList :: Word64Map a -> [(Key, a)]
+ GHC.Data.Word64Map.Internal: toList :: Word64Map a -> [(Key, a)]
+ GHC.Data.Word64Map.Internal: traverseMaybeMissing :: Applicative f => (Key -> x -> f (Maybe y)) -> WhenMissing f x y
+ GHC.Data.Word64Map.Internal: traverseMaybeWithKey :: Applicative f => (Key -> a -> f (Maybe b)) -> Word64Map a -> f (Word64Map b)
+ GHC.Data.Word64Map.Internal: traverseMissing :: Applicative f => (Key -> x -> f y) -> WhenMissing f x y
+ GHC.Data.Word64Map.Internal: traverseWithKey :: Applicative t => (Key -> a -> t b) -> Word64Map a -> t (Word64Map b)
+ GHC.Data.Word64Map.Internal: type Key = Word64
+ GHC.Data.Word64Map.Internal: type Mask = Word64
+ GHC.Data.Word64Map.Internal: type Nat = Word64
+ GHC.Data.Word64Map.Internal: type Prefix = Word64
+ GHC.Data.Word64Map.Internal: type SimpleWhenMatched = WhenMatched Identity
+ GHC.Data.Word64Map.Internal: type SimpleWhenMissing = WhenMissing Identity
+ GHC.Data.Word64Map.Internal: union :: Word64Map a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: unionWith :: (a -> a -> a) -> Word64Map a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: unionWithKey :: (Key -> a -> a -> a) -> Word64Map a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: unions :: Foldable f => f (Word64Map a) -> Word64Map a
+ GHC.Data.Word64Map.Internal: unionsWith :: Foldable f => (a -> a -> a) -> f (Word64Map a) -> Word64Map a
+ GHC.Data.Word64Map.Internal: update :: (a -> Maybe a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: updateLookupWithKey :: (Key -> a -> Maybe a) -> Key -> Word64Map a -> (Maybe a, Word64Map a)
+ GHC.Data.Word64Map.Internal: updateMax :: (a -> Maybe a) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: updateMaxWithKey :: (Key -> a -> Maybe a) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: updateMin :: (a -> Maybe a) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: updateMinWithKey :: (Key -> a -> Maybe a) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: updateWithKey :: (Key -> a -> Maybe a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Internal: withoutKeys :: Word64Map a -> Word64Set -> Word64Map a
+ GHC.Data.Word64Map.Internal: zero :: Key -> Mask -> Bool
+ GHC.Data.Word64Map.Internal: zipWithAMatched :: Applicative f => (Key -> x -> y -> f z) -> WhenMatched f x y z
+ GHC.Data.Word64Map.Internal: zipWithMatched :: forall (f :: Type -> Type) x y z. Applicative f => (Key -> x -> y -> z) -> WhenMatched f x y z
+ GHC.Data.Word64Map.Internal: zipWithMaybeAMatched :: (Key -> x -> y -> f (Maybe z)) -> WhenMatched f x y z
+ GHC.Data.Word64Map.Internal: zipWithMaybeMatched :: forall (f :: Type -> Type) x y z. Applicative f => (Key -> x -> y -> Maybe z) -> WhenMatched f x y z
+ GHC.Data.Word64Map.Lazy: (!) :: Word64Map a -> Key -> a
+ GHC.Data.Word64Map.Lazy: (!?) :: Word64Map a -> Key -> Maybe a
+ GHC.Data.Word64Map.Lazy: (\\) :: Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Lazy: adjust :: (a -> a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: adjustWithKey :: (Key -> a -> a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: alter :: (Maybe a -> Maybe a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: alterF :: Functor f => (Maybe a -> f (Maybe a)) -> Key -> Word64Map a -> f (Word64Map a)
+ GHC.Data.Word64Map.Lazy: assocs :: Word64Map a -> [(Key, a)]
+ GHC.Data.Word64Map.Lazy: compose :: Word64Map c -> Word64Map Word64 -> Word64Map c
+ GHC.Data.Word64Map.Lazy: data Word64Map a
+ GHC.Data.Word64Map.Lazy: delete :: Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: deleteFindMax :: Word64Map a -> ((Key, a), Word64Map a)
+ GHC.Data.Word64Map.Lazy: deleteFindMin :: Word64Map a -> ((Key, a), Word64Map a)
+ GHC.Data.Word64Map.Lazy: deleteMax :: Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: deleteMin :: Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: difference :: Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Lazy: differenceWith :: (a -> b -> Maybe a) -> Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Lazy: differenceWithKey :: (Key -> a -> b -> Maybe a) -> Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Lazy: disjoint :: Word64Map a -> Word64Map b -> Bool
+ GHC.Data.Word64Map.Lazy: dropWhileAntitone :: (Key -> Bool) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: elems :: Word64Map a -> [a]
+ GHC.Data.Word64Map.Lazy: empty :: Word64Map a
+ GHC.Data.Word64Map.Lazy: filter :: (a -> Bool) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: filterWithKey :: (Key -> a -> Bool) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: findMax :: Word64Map a -> (Key, a)
+ GHC.Data.Word64Map.Lazy: findMin :: Word64Map a -> (Key, a)
+ GHC.Data.Word64Map.Lazy: findWithDefault :: a -> Key -> Word64Map a -> a
+ GHC.Data.Word64Map.Lazy: foldMapWithKey :: Monoid m => (Key -> a -> m) -> Word64Map a -> m
+ GHC.Data.Word64Map.Lazy: foldl :: (a -> b -> a) -> a -> Word64Map b -> a
+ GHC.Data.Word64Map.Lazy: foldl' :: (a -> b -> a) -> a -> Word64Map b -> a
+ GHC.Data.Word64Map.Lazy: foldlWithKey :: (a -> Key -> b -> a) -> a -> Word64Map b -> a
+ GHC.Data.Word64Map.Lazy: foldlWithKey' :: (a -> Key -> b -> a) -> a -> Word64Map b -> a
+ GHC.Data.Word64Map.Lazy: foldr :: (a -> b -> b) -> b -> Word64Map a -> b
+ GHC.Data.Word64Map.Lazy: foldr' :: (a -> b -> b) -> b -> Word64Map a -> b
+ GHC.Data.Word64Map.Lazy: foldrWithKey :: (Key -> a -> b -> b) -> b -> Word64Map a -> b
+ GHC.Data.Word64Map.Lazy: foldrWithKey' :: (Key -> a -> b -> b) -> b -> Word64Map a -> b
+ GHC.Data.Word64Map.Lazy: fromAscList :: [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Lazy: fromAscListWith :: (a -> a -> a) -> [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Lazy: fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Lazy: fromDistinctAscList :: [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Lazy: fromList :: [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Lazy: fromListWith :: (a -> a -> a) -> [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Lazy: fromListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Lazy: fromSet :: (Key -> a) -> Word64Set -> Word64Map a
+ GHC.Data.Word64Map.Lazy: infixl 9 \\
+ GHC.Data.Word64Map.Lazy: insert :: Key -> a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> Word64Map a -> (Maybe a, Word64Map a)
+ GHC.Data.Word64Map.Lazy: insertWith :: (a -> a -> a) -> Key -> a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: intersection :: Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Lazy: intersectionWith :: (a -> b -> c) -> Word64Map a -> Word64Map b -> Word64Map c
+ GHC.Data.Word64Map.Lazy: intersectionWithKey :: (Key -> a -> b -> c) -> Word64Map a -> Word64Map b -> Word64Map c
+ GHC.Data.Word64Map.Lazy: isProperSubmapOf :: Eq a => Word64Map a -> Word64Map a -> Bool
+ GHC.Data.Word64Map.Lazy: isProperSubmapOfBy :: (a -> b -> Bool) -> Word64Map a -> Word64Map b -> Bool
+ GHC.Data.Word64Map.Lazy: isSubmapOf :: Eq a => Word64Map a -> Word64Map a -> Bool
+ GHC.Data.Word64Map.Lazy: isSubmapOfBy :: (a -> b -> Bool) -> Word64Map a -> Word64Map b -> Bool
+ GHC.Data.Word64Map.Lazy: keys :: Word64Map a -> [Key]
+ GHC.Data.Word64Map.Lazy: keysSet :: Word64Map a -> Word64Set
+ GHC.Data.Word64Map.Lazy: lookup :: Key -> Word64Map a -> Maybe a
+ GHC.Data.Word64Map.Lazy: lookupGE :: Key -> Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Lazy: lookupGT :: Key -> Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Lazy: lookupLE :: Key -> Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Lazy: lookupLT :: Key -> Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Lazy: lookupMax :: Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Lazy: lookupMin :: Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Lazy: map :: (a -> b) -> Word64Map a -> Word64Map b
+ GHC.Data.Word64Map.Lazy: mapAccum :: (a -> b -> (a, c)) -> a -> Word64Map b -> (a, Word64Map c)
+ GHC.Data.Word64Map.Lazy: mapAccumRWithKey :: (a -> Key -> b -> (a, c)) -> a -> Word64Map b -> (a, Word64Map c)
+ GHC.Data.Word64Map.Lazy: mapAccumWithKey :: (a -> Key -> b -> (a, c)) -> a -> Word64Map b -> (a, Word64Map c)
+ GHC.Data.Word64Map.Lazy: mapEither :: (a -> Either b c) -> Word64Map a -> (Word64Map b, Word64Map c)
+ GHC.Data.Word64Map.Lazy: mapEitherWithKey :: (Key -> a -> Either b c) -> Word64Map a -> (Word64Map b, Word64Map c)
+ GHC.Data.Word64Map.Lazy: mapKeys :: (Key -> Key) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: mapKeysMonotonic :: (Key -> Key) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: mapKeysWith :: (a -> a -> a) -> (Key -> Key) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: mapMaybe :: (a -> Maybe b) -> Word64Map a -> Word64Map b
+ GHC.Data.Word64Map.Lazy: mapMaybeWithKey :: (Key -> a -> Maybe b) -> Word64Map a -> Word64Map b
+ GHC.Data.Word64Map.Lazy: mapWithKey :: (Key -> a -> b) -> Word64Map a -> Word64Map b
+ GHC.Data.Word64Map.Lazy: maxView :: Word64Map a -> Maybe (a, Word64Map a)
+ GHC.Data.Word64Map.Lazy: maxViewWithKey :: Word64Map a -> Maybe ((Key, a), Word64Map a)
+ GHC.Data.Word64Map.Lazy: member :: Key -> Word64Map a -> Bool
+ GHC.Data.Word64Map.Lazy: mergeWithKey :: (Key -> a -> b -> Maybe c) -> (Word64Map a -> Word64Map c) -> (Word64Map b -> Word64Map c) -> Word64Map a -> Word64Map b -> Word64Map c
+ GHC.Data.Word64Map.Lazy: minView :: Word64Map a -> Maybe (a, Word64Map a)
+ GHC.Data.Word64Map.Lazy: minViewWithKey :: Word64Map a -> Maybe ((Key, a), Word64Map a)
+ GHC.Data.Word64Map.Lazy: notMember :: Key -> Word64Map a -> Bool
+ GHC.Data.Word64Map.Lazy: null :: Word64Map a -> Bool
+ GHC.Data.Word64Map.Lazy: partition :: (a -> Bool) -> Word64Map a -> (Word64Map a, Word64Map a)
+ GHC.Data.Word64Map.Lazy: partitionWithKey :: (Key -> a -> Bool) -> Word64Map a -> (Word64Map a, Word64Map a)
+ GHC.Data.Word64Map.Lazy: restrictKeys :: Word64Map a -> Word64Set -> Word64Map a
+ GHC.Data.Word64Map.Lazy: singleton :: Key -> a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: size :: Word64Map a -> Int
+ GHC.Data.Word64Map.Lazy: spanAntitone :: (Key -> Bool) -> Word64Map a -> (Word64Map a, Word64Map a)
+ GHC.Data.Word64Map.Lazy: split :: Key -> Word64Map a -> (Word64Map a, Word64Map a)
+ GHC.Data.Word64Map.Lazy: splitLookup :: Key -> Word64Map a -> (Word64Map a, Maybe a, Word64Map a)
+ GHC.Data.Word64Map.Lazy: splitRoot :: Word64Map a -> [Word64Map a]
+ GHC.Data.Word64Map.Lazy: takeWhileAntitone :: (Key -> Bool) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: toAscList :: Word64Map a -> [(Key, a)]
+ GHC.Data.Word64Map.Lazy: toDescList :: Word64Map a -> [(Key, a)]
+ GHC.Data.Word64Map.Lazy: toList :: Word64Map a -> [(Key, a)]
+ GHC.Data.Word64Map.Lazy: traverseMaybeWithKey :: Applicative f => (Key -> a -> f (Maybe b)) -> Word64Map a -> f (Word64Map b)
+ GHC.Data.Word64Map.Lazy: traverseWithKey :: Applicative t => (Key -> a -> t b) -> Word64Map a -> t (Word64Map b)
+ GHC.Data.Word64Map.Lazy: type Key = Word64
+ GHC.Data.Word64Map.Lazy: union :: Word64Map a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: unionWith :: (a -> a -> a) -> Word64Map a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: unionWithKey :: (Key -> a -> a -> a) -> Word64Map a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: unions :: Foldable f => f (Word64Map a) -> Word64Map a
+ GHC.Data.Word64Map.Lazy: unionsWith :: Foldable f => (a -> a -> a) -> f (Word64Map a) -> Word64Map a
+ GHC.Data.Word64Map.Lazy: update :: (a -> Maybe a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: updateLookupWithKey :: (Key -> a -> Maybe a) -> Key -> Word64Map a -> (Maybe a, Word64Map a)
+ GHC.Data.Word64Map.Lazy: updateMax :: (a -> Maybe a) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: updateMaxWithKey :: (Key -> a -> Maybe a) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: updateMin :: (a -> Maybe a) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: updateMinWithKey :: (Key -> a -> Maybe a) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: updateWithKey :: (Key -> a -> Maybe a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Lazy: withoutKeys :: Word64Map a -> Word64Set -> Word64Map a
+ GHC.Data.Word64Map.Strict: (!) :: Word64Map a -> Key -> a
+ GHC.Data.Word64Map.Strict: (!?) :: Word64Map a -> Key -> Maybe a
+ GHC.Data.Word64Map.Strict: (\\) :: Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Strict: adjust :: (a -> a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: adjustWithKey :: (Key -> a -> a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: alter :: (Maybe a -> Maybe a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: alterF :: Functor f => (Maybe a -> f (Maybe a)) -> Key -> Word64Map a -> f (Word64Map a)
+ GHC.Data.Word64Map.Strict: assocs :: Word64Map a -> [(Key, a)]
+ GHC.Data.Word64Map.Strict: compose :: Word64Map c -> Word64Map Word64 -> Word64Map c
+ GHC.Data.Word64Map.Strict: data Word64Map a
+ GHC.Data.Word64Map.Strict: delete :: Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: deleteFindMax :: Word64Map a -> ((Key, a), Word64Map a)
+ GHC.Data.Word64Map.Strict: deleteFindMin :: Word64Map a -> ((Key, a), Word64Map a)
+ GHC.Data.Word64Map.Strict: deleteMax :: Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: deleteMin :: Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: difference :: Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Strict: differenceWith :: (a -> b -> Maybe a) -> Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Strict: differenceWithKey :: (Key -> a -> b -> Maybe a) -> Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Strict: disjoint :: Word64Map a -> Word64Map b -> Bool
+ GHC.Data.Word64Map.Strict: dropWhileAntitone :: (Key -> Bool) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: elems :: Word64Map a -> [a]
+ GHC.Data.Word64Map.Strict: empty :: Word64Map a
+ GHC.Data.Word64Map.Strict: filter :: (a -> Bool) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: filterWithKey :: (Key -> a -> Bool) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: findMax :: Word64Map a -> (Key, a)
+ GHC.Data.Word64Map.Strict: findMin :: Word64Map a -> (Key, a)
+ GHC.Data.Word64Map.Strict: findWithDefault :: a -> Key -> Word64Map a -> a
+ GHC.Data.Word64Map.Strict: foldMapWithKey :: Monoid m => (Key -> a -> m) -> Word64Map a -> m
+ GHC.Data.Word64Map.Strict: foldl :: (a -> b -> a) -> a -> Word64Map b -> a
+ GHC.Data.Word64Map.Strict: foldl' :: (a -> b -> a) -> a -> Word64Map b -> a
+ GHC.Data.Word64Map.Strict: foldlWithKey :: (a -> Key -> b -> a) -> a -> Word64Map b -> a
+ GHC.Data.Word64Map.Strict: foldlWithKey' :: (a -> Key -> b -> a) -> a -> Word64Map b -> a
+ GHC.Data.Word64Map.Strict: foldr :: (a -> b -> b) -> b -> Word64Map a -> b
+ GHC.Data.Word64Map.Strict: foldr' :: (a -> b -> b) -> b -> Word64Map a -> b
+ GHC.Data.Word64Map.Strict: foldrWithKey :: (Key -> a -> b -> b) -> b -> Word64Map a -> b
+ GHC.Data.Word64Map.Strict: foldrWithKey' :: (Key -> a -> b -> b) -> b -> Word64Map a -> b
+ GHC.Data.Word64Map.Strict: fromAscList :: [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Strict: fromAscListWith :: (a -> a -> a) -> [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Strict: fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Strict: fromDistinctAscList :: [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Strict: fromList :: [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Strict: fromListWith :: (a -> a -> a) -> [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Strict: fromListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Strict: fromSet :: (Key -> a) -> Word64Set -> Word64Map a
+ GHC.Data.Word64Map.Strict: infixl 9 \\
+ GHC.Data.Word64Map.Strict: insert :: Key -> a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> Word64Map a -> (Maybe a, Word64Map a)
+ GHC.Data.Word64Map.Strict: insertWith :: (a -> a -> a) -> Key -> a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: intersection :: Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Strict: intersectionWith :: (a -> b -> c) -> Word64Map a -> Word64Map b -> Word64Map c
+ GHC.Data.Word64Map.Strict: intersectionWithKey :: (Key -> a -> b -> c) -> Word64Map a -> Word64Map b -> Word64Map c
+ GHC.Data.Word64Map.Strict: isProperSubmapOf :: Eq a => Word64Map a -> Word64Map a -> Bool
+ GHC.Data.Word64Map.Strict: isProperSubmapOfBy :: (a -> b -> Bool) -> Word64Map a -> Word64Map b -> Bool
+ GHC.Data.Word64Map.Strict: isSubmapOf :: Eq a => Word64Map a -> Word64Map a -> Bool
+ GHC.Data.Word64Map.Strict: isSubmapOfBy :: (a -> b -> Bool) -> Word64Map a -> Word64Map b -> Bool
+ GHC.Data.Word64Map.Strict: keys :: Word64Map a -> [Key]
+ GHC.Data.Word64Map.Strict: keysSet :: Word64Map a -> Word64Set
+ GHC.Data.Word64Map.Strict: lookup :: Key -> Word64Map a -> Maybe a
+ GHC.Data.Word64Map.Strict: lookupGE :: Key -> Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Strict: lookupGT :: Key -> Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Strict: lookupLE :: Key -> Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Strict: lookupLT :: Key -> Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Strict: lookupMax :: Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Strict: lookupMin :: Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Strict: map :: (a -> b) -> Word64Map a -> Word64Map b
+ GHC.Data.Word64Map.Strict: mapAccum :: (a -> b -> (a, c)) -> a -> Word64Map b -> (a, Word64Map c)
+ GHC.Data.Word64Map.Strict: mapAccumRWithKey :: (a -> Key -> b -> (a, c)) -> a -> Word64Map b -> (a, Word64Map c)
+ GHC.Data.Word64Map.Strict: mapAccumWithKey :: (a -> Key -> b -> (a, c)) -> a -> Word64Map b -> (a, Word64Map c)
+ GHC.Data.Word64Map.Strict: mapEither :: (a -> Either b c) -> Word64Map a -> (Word64Map b, Word64Map c)
+ GHC.Data.Word64Map.Strict: mapEitherWithKey :: (Key -> a -> Either b c) -> Word64Map a -> (Word64Map b, Word64Map c)
+ GHC.Data.Word64Map.Strict: mapKeys :: (Key -> Key) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: mapKeysMonotonic :: (Key -> Key) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: mapKeysWith :: (a -> a -> a) -> (Key -> Key) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: mapMaybe :: (a -> Maybe b) -> Word64Map a -> Word64Map b
+ GHC.Data.Word64Map.Strict: mapMaybeWithKey :: (Key -> a -> Maybe b) -> Word64Map a -> Word64Map b
+ GHC.Data.Word64Map.Strict: mapWithKey :: (Key -> a -> b) -> Word64Map a -> Word64Map b
+ GHC.Data.Word64Map.Strict: maxView :: Word64Map a -> Maybe (a, Word64Map a)
+ GHC.Data.Word64Map.Strict: maxViewWithKey :: Word64Map a -> Maybe ((Key, a), Word64Map a)
+ GHC.Data.Word64Map.Strict: member :: Key -> Word64Map a -> Bool
+ GHC.Data.Word64Map.Strict: mergeWithKey :: (Key -> a -> b -> Maybe c) -> (Word64Map a -> Word64Map c) -> (Word64Map b -> Word64Map c) -> Word64Map a -> Word64Map b -> Word64Map c
+ GHC.Data.Word64Map.Strict: minView :: Word64Map a -> Maybe (a, Word64Map a)
+ GHC.Data.Word64Map.Strict: minViewWithKey :: Word64Map a -> Maybe ((Key, a), Word64Map a)
+ GHC.Data.Word64Map.Strict: notMember :: Key -> Word64Map a -> Bool
+ GHC.Data.Word64Map.Strict: null :: Word64Map a -> Bool
+ GHC.Data.Word64Map.Strict: partition :: (a -> Bool) -> Word64Map a -> (Word64Map a, Word64Map a)
+ GHC.Data.Word64Map.Strict: partitionWithKey :: (Key -> a -> Bool) -> Word64Map a -> (Word64Map a, Word64Map a)
+ GHC.Data.Word64Map.Strict: restrictKeys :: Word64Map a -> Word64Set -> Word64Map a
+ GHC.Data.Word64Map.Strict: singleton :: Key -> a -> Word64Map a
+ GHC.Data.Word64Map.Strict: size :: Word64Map a -> Int
+ GHC.Data.Word64Map.Strict: spanAntitone :: (Key -> Bool) -> Word64Map a -> (Word64Map a, Word64Map a)
+ GHC.Data.Word64Map.Strict: split :: Key -> Word64Map a -> (Word64Map a, Word64Map a)
+ GHC.Data.Word64Map.Strict: splitLookup :: Key -> Word64Map a -> (Word64Map a, Maybe a, Word64Map a)
+ GHC.Data.Word64Map.Strict: splitRoot :: Word64Map a -> [Word64Map a]
+ GHC.Data.Word64Map.Strict: takeWhileAntitone :: (Key -> Bool) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: toAscList :: Word64Map a -> [(Key, a)]
+ GHC.Data.Word64Map.Strict: toDescList :: Word64Map a -> [(Key, a)]
+ GHC.Data.Word64Map.Strict: toList :: Word64Map a -> [(Key, a)]
+ GHC.Data.Word64Map.Strict: traverseMaybeWithKey :: Applicative f => (Key -> a -> f (Maybe b)) -> Word64Map a -> f (Word64Map b)
+ GHC.Data.Word64Map.Strict: traverseWithKey :: Applicative t => (Key -> a -> t b) -> Word64Map a -> t (Word64Map b)
+ GHC.Data.Word64Map.Strict: type Key = Word64
+ GHC.Data.Word64Map.Strict: union :: Word64Map a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: unionWith :: (a -> a -> a) -> Word64Map a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: unionWithKey :: (Key -> a -> a -> a) -> Word64Map a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: unions :: Foldable f => f (Word64Map a) -> Word64Map a
+ GHC.Data.Word64Map.Strict: unionsWith :: Foldable f => (a -> a -> a) -> f (Word64Map a) -> Word64Map a
+ GHC.Data.Word64Map.Strict: update :: (a -> Maybe a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: updateLookupWithKey :: (Key -> a -> Maybe a) -> Key -> Word64Map a -> (Maybe a, Word64Map a)
+ GHC.Data.Word64Map.Strict: updateMax :: (a -> Maybe a) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: updateMaxWithKey :: (Key -> a -> Maybe a) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: updateMin :: (a -> Maybe a) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: updateMinWithKey :: (Key -> a -> Maybe a) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: updateWithKey :: (Key -> a -> Maybe a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict: withoutKeys :: Word64Map a -> Word64Set -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: (!) :: Word64Map a -> Key -> a
+ GHC.Data.Word64Map.Strict.Internal: (!?) :: Word64Map a -> Key -> Maybe a
+ GHC.Data.Word64Map.Strict.Internal: (\\) :: Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: adjust :: (a -> a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: adjustWithKey :: (Key -> a -> a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: alter :: (Maybe a -> Maybe a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: alterF :: Functor f => (Maybe a -> f (Maybe a)) -> Key -> Word64Map a -> f (Word64Map a)
+ GHC.Data.Word64Map.Strict.Internal: assocs :: Word64Map a -> [(Key, a)]
+ GHC.Data.Word64Map.Strict.Internal: compose :: Word64Map c -> Word64Map Word64 -> Word64Map c
+ GHC.Data.Word64Map.Strict.Internal: data Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: delete :: Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: deleteFindMax :: Word64Map a -> ((Key, a), Word64Map a)
+ GHC.Data.Word64Map.Strict.Internal: deleteFindMin :: Word64Map a -> ((Key, a), Word64Map a)
+ GHC.Data.Word64Map.Strict.Internal: deleteMax :: Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: deleteMin :: Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: difference :: Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: differenceWith :: (a -> b -> Maybe a) -> Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: differenceWithKey :: (Key -> a -> b -> Maybe a) -> Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: disjoint :: Word64Map a -> Word64Map b -> Bool
+ GHC.Data.Word64Map.Strict.Internal: dropWhileAntitone :: (Key -> Bool) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: elems :: Word64Map a -> [a]
+ GHC.Data.Word64Map.Strict.Internal: empty :: Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: filter :: (a -> Bool) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: filterWithKey :: (Key -> a -> Bool) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: findMax :: Word64Map a -> (Key, a)
+ GHC.Data.Word64Map.Strict.Internal: findMin :: Word64Map a -> (Key, a)
+ GHC.Data.Word64Map.Strict.Internal: findWithDefault :: a -> Key -> Word64Map a -> a
+ GHC.Data.Word64Map.Strict.Internal: foldMapWithKey :: Monoid m => (Key -> a -> m) -> Word64Map a -> m
+ GHC.Data.Word64Map.Strict.Internal: foldl :: (a -> b -> a) -> a -> Word64Map b -> a
+ GHC.Data.Word64Map.Strict.Internal: foldl' :: (a -> b -> a) -> a -> Word64Map b -> a
+ GHC.Data.Word64Map.Strict.Internal: foldlWithKey :: (a -> Key -> b -> a) -> a -> Word64Map b -> a
+ GHC.Data.Word64Map.Strict.Internal: foldlWithKey' :: (a -> Key -> b -> a) -> a -> Word64Map b -> a
+ GHC.Data.Word64Map.Strict.Internal: foldr :: (a -> b -> b) -> b -> Word64Map a -> b
+ GHC.Data.Word64Map.Strict.Internal: foldr' :: (a -> b -> b) -> b -> Word64Map a -> b
+ GHC.Data.Word64Map.Strict.Internal: foldrWithKey :: (Key -> a -> b -> b) -> b -> Word64Map a -> b
+ GHC.Data.Word64Map.Strict.Internal: foldrWithKey' :: (Key -> a -> b -> b) -> b -> Word64Map a -> b
+ GHC.Data.Word64Map.Strict.Internal: fromAscList :: [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: fromAscListWith :: (a -> a -> a) -> [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: fromDistinctAscList :: [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: fromList :: [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: fromListWith :: (a -> a -> a) -> [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: fromListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: fromSet :: (Key -> a) -> Word64Set -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: infixl 9 \\
+ GHC.Data.Word64Map.Strict.Internal: insert :: Key -> a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> Word64Map a -> (Maybe a, Word64Map a)
+ GHC.Data.Word64Map.Strict.Internal: insertWith :: (a -> a -> a) -> Key -> a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: intersection :: Word64Map a -> Word64Map b -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: intersectionWith :: (a -> b -> c) -> Word64Map a -> Word64Map b -> Word64Map c
+ GHC.Data.Word64Map.Strict.Internal: intersectionWithKey :: (Key -> a -> b -> c) -> Word64Map a -> Word64Map b -> Word64Map c
+ GHC.Data.Word64Map.Strict.Internal: isProperSubmapOf :: Eq a => Word64Map a -> Word64Map a -> Bool
+ GHC.Data.Word64Map.Strict.Internal: isProperSubmapOfBy :: (a -> b -> Bool) -> Word64Map a -> Word64Map b -> Bool
+ GHC.Data.Word64Map.Strict.Internal: isSubmapOf :: Eq a => Word64Map a -> Word64Map a -> Bool
+ GHC.Data.Word64Map.Strict.Internal: isSubmapOfBy :: (a -> b -> Bool) -> Word64Map a -> Word64Map b -> Bool
+ GHC.Data.Word64Map.Strict.Internal: keys :: Word64Map a -> [Key]
+ GHC.Data.Word64Map.Strict.Internal: keysSet :: Word64Map a -> Word64Set
+ GHC.Data.Word64Map.Strict.Internal: lookup :: Key -> Word64Map a -> Maybe a
+ GHC.Data.Word64Map.Strict.Internal: lookupGE :: Key -> Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Strict.Internal: lookupGT :: Key -> Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Strict.Internal: lookupLE :: Key -> Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Strict.Internal: lookupLT :: Key -> Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Strict.Internal: lookupMax :: Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Strict.Internal: lookupMin :: Word64Map a -> Maybe (Key, a)
+ GHC.Data.Word64Map.Strict.Internal: map :: (a -> b) -> Word64Map a -> Word64Map b
+ GHC.Data.Word64Map.Strict.Internal: mapAccum :: (a -> b -> (a, c)) -> a -> Word64Map b -> (a, Word64Map c)
+ GHC.Data.Word64Map.Strict.Internal: mapAccumRWithKey :: (a -> Key -> b -> (a, c)) -> a -> Word64Map b -> (a, Word64Map c)
+ GHC.Data.Word64Map.Strict.Internal: mapAccumWithKey :: (a -> Key -> b -> (a, c)) -> a -> Word64Map b -> (a, Word64Map c)
+ GHC.Data.Word64Map.Strict.Internal: mapEither :: (a -> Either b c) -> Word64Map a -> (Word64Map b, Word64Map c)
+ GHC.Data.Word64Map.Strict.Internal: mapEitherWithKey :: (Key -> a -> Either b c) -> Word64Map a -> (Word64Map b, Word64Map c)
+ GHC.Data.Word64Map.Strict.Internal: mapKeys :: (Key -> Key) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: mapKeysMonotonic :: (Key -> Key) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: mapKeysWith :: (a -> a -> a) -> (Key -> Key) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: mapMaybe :: (a -> Maybe b) -> Word64Map a -> Word64Map b
+ GHC.Data.Word64Map.Strict.Internal: mapMaybeWithKey :: (Key -> a -> Maybe b) -> Word64Map a -> Word64Map b
+ GHC.Data.Word64Map.Strict.Internal: mapWithKey :: (Key -> a -> b) -> Word64Map a -> Word64Map b
+ GHC.Data.Word64Map.Strict.Internal: maxView :: Word64Map a -> Maybe (a, Word64Map a)
+ GHC.Data.Word64Map.Strict.Internal: maxViewWithKey :: Word64Map a -> Maybe ((Key, a), Word64Map a)
+ GHC.Data.Word64Map.Strict.Internal: member :: Key -> Word64Map a -> Bool
+ GHC.Data.Word64Map.Strict.Internal: mergeWithKey :: (Key -> a -> b -> Maybe c) -> (Word64Map a -> Word64Map c) -> (Word64Map b -> Word64Map c) -> Word64Map a -> Word64Map b -> Word64Map c
+ GHC.Data.Word64Map.Strict.Internal: minView :: Word64Map a -> Maybe (a, Word64Map a)
+ GHC.Data.Word64Map.Strict.Internal: minViewWithKey :: Word64Map a -> Maybe ((Key, a), Word64Map a)
+ GHC.Data.Word64Map.Strict.Internal: notMember :: Key -> Word64Map a -> Bool
+ GHC.Data.Word64Map.Strict.Internal: null :: Word64Map a -> Bool
+ GHC.Data.Word64Map.Strict.Internal: partition :: (a -> Bool) -> Word64Map a -> (Word64Map a, Word64Map a)
+ GHC.Data.Word64Map.Strict.Internal: partitionWithKey :: (Key -> a -> Bool) -> Word64Map a -> (Word64Map a, Word64Map a)
+ GHC.Data.Word64Map.Strict.Internal: restrictKeys :: Word64Map a -> Word64Set -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: singleton :: Key -> a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: size :: Word64Map a -> Int
+ GHC.Data.Word64Map.Strict.Internal: spanAntitone :: (Key -> Bool) -> Word64Map a -> (Word64Map a, Word64Map a)
+ GHC.Data.Word64Map.Strict.Internal: split :: Key -> Word64Map a -> (Word64Map a, Word64Map a)
+ GHC.Data.Word64Map.Strict.Internal: splitLookup :: Key -> Word64Map a -> (Word64Map a, Maybe a, Word64Map a)
+ GHC.Data.Word64Map.Strict.Internal: splitRoot :: Word64Map a -> [Word64Map a]
+ GHC.Data.Word64Map.Strict.Internal: takeWhileAntitone :: (Key -> Bool) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: toAscList :: Word64Map a -> [(Key, a)]
+ GHC.Data.Word64Map.Strict.Internal: toDescList :: Word64Map a -> [(Key, a)]
+ GHC.Data.Word64Map.Strict.Internal: toList :: Word64Map a -> [(Key, a)]
+ GHC.Data.Word64Map.Strict.Internal: traverseMaybeWithKey :: Applicative f => (Key -> a -> f (Maybe b)) -> Word64Map a -> f (Word64Map b)
+ GHC.Data.Word64Map.Strict.Internal: traverseWithKey :: Applicative t => (Key -> a -> t b) -> Word64Map a -> t (Word64Map b)
+ GHC.Data.Word64Map.Strict.Internal: type Key = Word64
+ GHC.Data.Word64Map.Strict.Internal: union :: Word64Map a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: unionWith :: (a -> a -> a) -> Word64Map a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: unionWithKey :: (Key -> a -> a -> a) -> Word64Map a -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: unions :: Foldable f => f (Word64Map a) -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: unionsWith :: Foldable f => (a -> a -> a) -> f (Word64Map a) -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: update :: (a -> Maybe a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: updateLookupWithKey :: (Key -> a -> Maybe a) -> Key -> Word64Map a -> (Maybe a, Word64Map a)
+ GHC.Data.Word64Map.Strict.Internal: updateMax :: (a -> Maybe a) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: updateMaxWithKey :: (Key -> a -> Maybe a) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: updateMin :: (a -> Maybe a) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: updateMinWithKey :: (Key -> a -> Maybe a) -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: updateWithKey :: (Key -> a -> Maybe a) -> Key -> Word64Map a -> Word64Map a
+ GHC.Data.Word64Map.Strict.Internal: withoutKeys :: Word64Map a -> Word64Set -> Word64Map a
+ GHC.Data.Word64Set: (\\) :: Word64Set -> Word64Set -> Word64Set
+ GHC.Data.Word64Set: alterF :: Functor f => (Bool -> f Bool) -> Key -> Word64Set -> f Word64Set
+ GHC.Data.Word64Set: data Word64Set
+ GHC.Data.Word64Set: delete :: Key -> Word64Set -> Word64Set
+ GHC.Data.Word64Set: deleteFindMax :: Word64Set -> (Key, Word64Set)
+ GHC.Data.Word64Set: deleteFindMin :: Word64Set -> (Key, Word64Set)
+ GHC.Data.Word64Set: deleteMax :: Word64Set -> Word64Set
+ GHC.Data.Word64Set: deleteMin :: Word64Set -> Word64Set
+ GHC.Data.Word64Set: difference :: Word64Set -> Word64Set -> Word64Set
+ GHC.Data.Word64Set: disjoint :: Word64Set -> Word64Set -> Bool
+ GHC.Data.Word64Set: dropWhileAntitone :: (Key -> Bool) -> Word64Set -> Word64Set
+ GHC.Data.Word64Set: elems :: Word64Set -> [Key]
+ GHC.Data.Word64Set: empty :: Word64Set
+ GHC.Data.Word64Set: filter :: (Key -> Bool) -> Word64Set -> Word64Set
+ GHC.Data.Word64Set: findMax :: Word64Set -> Key
+ GHC.Data.Word64Set: findMin :: Word64Set -> Key
+ GHC.Data.Word64Set: fold :: (Key -> b -> b) -> b -> Word64Set -> b
+ GHC.Data.Word64Set: foldl :: (a -> Key -> a) -> a -> Word64Set -> a
+ GHC.Data.Word64Set: foldl' :: (a -> Key -> a) -> a -> Word64Set -> a
+ GHC.Data.Word64Set: foldr :: (Key -> b -> b) -> b -> Word64Set -> b
+ GHC.Data.Word64Set: foldr' :: (Key -> b -> b) -> b -> Word64Set -> b
+ GHC.Data.Word64Set: fromAscList :: [Key] -> Word64Set
+ GHC.Data.Word64Set: fromDistinctAscList :: [Key] -> Word64Set
+ GHC.Data.Word64Set: fromList :: [Key] -> Word64Set
+ GHC.Data.Word64Set: infixl 9 \\
+ GHC.Data.Word64Set: insert :: Key -> Word64Set -> Word64Set
+ GHC.Data.Word64Set: intersection :: Word64Set -> Word64Set -> Word64Set
+ GHC.Data.Word64Set: isProperSubsetOf :: Word64Set -> Word64Set -> Bool
+ GHC.Data.Word64Set: isSubsetOf :: Word64Set -> Word64Set -> Bool
+ GHC.Data.Word64Set: lookupGE :: Key -> Word64Set -> Maybe Key
+ GHC.Data.Word64Set: lookupGT :: Key -> Word64Set -> Maybe Key
+ GHC.Data.Word64Set: lookupLE :: Key -> Word64Set -> Maybe Key
+ GHC.Data.Word64Set: lookupLT :: Key -> Word64Set -> Maybe Key
+ GHC.Data.Word64Set: map :: (Key -> Key) -> Word64Set -> Word64Set
+ GHC.Data.Word64Set: mapMonotonic :: (Key -> Key) -> Word64Set -> Word64Set
+ GHC.Data.Word64Set: maxView :: Word64Set -> Maybe (Key, Word64Set)
+ GHC.Data.Word64Set: member :: Key -> Word64Set -> Bool
+ GHC.Data.Word64Set: minView :: Word64Set -> Maybe (Key, Word64Set)
+ GHC.Data.Word64Set: notMember :: Key -> Word64Set -> Bool
+ GHC.Data.Word64Set: null :: Word64Set -> Bool
+ GHC.Data.Word64Set: partition :: (Key -> Bool) -> Word64Set -> (Word64Set, Word64Set)
+ GHC.Data.Word64Set: showTree :: Word64Set -> String
+ GHC.Data.Word64Set: showTreeWith :: Bool -> Bool -> Word64Set -> String
+ GHC.Data.Word64Set: singleton :: Key -> Word64Set
+ GHC.Data.Word64Set: size :: Word64Set -> Int
+ GHC.Data.Word64Set: spanAntitone :: (Key -> Bool) -> Word64Set -> (Word64Set, Word64Set)
+ GHC.Data.Word64Set: split :: Key -> Word64Set -> (Word64Set, Word64Set)
+ GHC.Data.Word64Set: splitMember :: Key -> Word64Set -> (Word64Set, Bool, Word64Set)
+ GHC.Data.Word64Set: splitRoot :: Word64Set -> [Word64Set]
+ GHC.Data.Word64Set: takeWhileAntitone :: (Key -> Bool) -> Word64Set -> Word64Set
+ GHC.Data.Word64Set: toAscList :: Word64Set -> [Key]
+ GHC.Data.Word64Set: toDescList :: Word64Set -> [Key]
+ GHC.Data.Word64Set: toList :: Word64Set -> [Key]
+ GHC.Data.Word64Set: type Key = Word64
+ GHC.Data.Word64Set: union :: Word64Set -> Word64Set -> Word64Set
+ GHC.Data.Word64Set: unions :: Foldable f => f Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: (\\) :: Word64Set -> Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: Bin :: {-# UNPACK #-} !Prefix -> {-# UNPACK #-} !Mask -> !Word64Set -> !Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: Nil :: Word64Set
+ GHC.Data.Word64Set.Internal: Tip :: {-# UNPACK #-} !Prefix -> {-# UNPACK #-} !BitMap -> Word64Set
+ GHC.Data.Word64Set.Internal: alterF :: Functor f => (Bool -> f Bool) -> Key -> Word64Set -> f Word64Set
+ GHC.Data.Word64Set.Internal: bitmapOf :: Word64 -> BitMap
+ GHC.Data.Word64Set.Internal: data Word64Set
+ GHC.Data.Word64Set.Internal: delete :: Key -> Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: deleteFindMax :: Word64Set -> (Key, Word64Set)
+ GHC.Data.Word64Set.Internal: deleteFindMin :: Word64Set -> (Key, Word64Set)
+ GHC.Data.Word64Set.Internal: deleteMax :: Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: deleteMin :: Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: difference :: Word64Set -> Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: disjoint :: Word64Set -> Word64Set -> Bool
+ GHC.Data.Word64Set.Internal: dropWhileAntitone :: (Key -> Bool) -> Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: elems :: Word64Set -> [Key]
+ GHC.Data.Word64Set.Internal: empty :: Word64Set
+ GHC.Data.Word64Set.Internal: filter :: (Key -> Bool) -> Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: findMax :: Word64Set -> Key
+ GHC.Data.Word64Set.Internal: findMin :: Word64Set -> Key
+ GHC.Data.Word64Set.Internal: fold :: (Key -> b -> b) -> b -> Word64Set -> b
+ GHC.Data.Word64Set.Internal: foldl :: (a -> Key -> a) -> a -> Word64Set -> a
+ GHC.Data.Word64Set.Internal: foldl' :: (a -> Key -> a) -> a -> Word64Set -> a
+ GHC.Data.Word64Set.Internal: foldr :: (Key -> b -> b) -> b -> Word64Set -> b
+ GHC.Data.Word64Set.Internal: foldr' :: (Key -> b -> b) -> b -> Word64Set -> b
+ GHC.Data.Word64Set.Internal: fromAscList :: [Key] -> Word64Set
+ GHC.Data.Word64Set.Internal: fromDistinctAscList :: [Key] -> Word64Set
+ GHC.Data.Word64Set.Internal: fromList :: [Key] -> Word64Set
+ GHC.Data.Word64Set.Internal: infixl 9 \\
+ GHC.Data.Word64Set.Internal: insert :: Key -> Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: instance Control.DeepSeq.NFData GHC.Data.Word64Set.Internal.Word64Set
+ GHC.Data.Word64Set.Internal: instance Data.Data.Data GHC.Data.Word64Set.Internal.Word64Set
+ GHC.Data.Word64Set.Internal: instance GHC.Base.Monoid GHC.Data.Word64Set.Internal.Word64Set
+ GHC.Data.Word64Set.Internal: instance GHC.Base.Semigroup GHC.Data.Word64Set.Internal.Word64Set
+ GHC.Data.Word64Set.Internal: instance GHC.Classes.Eq GHC.Data.Word64Set.Internal.Word64Set
+ GHC.Data.Word64Set.Internal: instance GHC.Classes.Ord GHC.Data.Word64Set.Internal.Word64Set
+ GHC.Data.Word64Set.Internal: instance GHC.IsList.IsList GHC.Data.Word64Set.Internal.Word64Set
+ GHC.Data.Word64Set.Internal: instance GHC.Read.Read GHC.Data.Word64Set.Internal.Word64Set
+ GHC.Data.Word64Set.Internal: instance GHC.Show.Show GHC.Data.Word64Set.Internal.Word64Set
+ GHC.Data.Word64Set.Internal: intersection :: Word64Set -> Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: isProperSubsetOf :: Word64Set -> Word64Set -> Bool
+ GHC.Data.Word64Set.Internal: isSubsetOf :: Word64Set -> Word64Set -> Bool
+ GHC.Data.Word64Set.Internal: lookupGE :: Key -> Word64Set -> Maybe Key
+ GHC.Data.Word64Set.Internal: lookupGT :: Key -> Word64Set -> Maybe Key
+ GHC.Data.Word64Set.Internal: lookupLE :: Key -> Word64Set -> Maybe Key
+ GHC.Data.Word64Set.Internal: lookupLT :: Key -> Word64Set -> Maybe Key
+ GHC.Data.Word64Set.Internal: map :: (Key -> Key) -> Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: mapMonotonic :: (Key -> Key) -> Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: match :: Word64 -> Prefix -> Mask -> Bool
+ GHC.Data.Word64Set.Internal: maxView :: Word64Set -> Maybe (Key, Word64Set)
+ GHC.Data.Word64Set.Internal: member :: Key -> Word64Set -> Bool
+ GHC.Data.Word64Set.Internal: minView :: Word64Set -> Maybe (Key, Word64Set)
+ GHC.Data.Word64Set.Internal: notMember :: Key -> Word64Set -> Bool
+ GHC.Data.Word64Set.Internal: null :: Word64Set -> Bool
+ GHC.Data.Word64Set.Internal: partition :: (Key -> Bool) -> Word64Set -> (Word64Set, Word64Set)
+ GHC.Data.Word64Set.Internal: prefixBitMask :: Word64
+ GHC.Data.Word64Set.Internal: showTree :: Word64Set -> String
+ GHC.Data.Word64Set.Internal: showTreeWith :: Bool -> Bool -> Word64Set -> String
+ GHC.Data.Word64Set.Internal: singleton :: Key -> Word64Set
+ GHC.Data.Word64Set.Internal: size :: Word64Set -> Int
+ GHC.Data.Word64Set.Internal: spanAntitone :: (Key -> Bool) -> Word64Set -> (Word64Set, Word64Set)
+ GHC.Data.Word64Set.Internal: split :: Key -> Word64Set -> (Word64Set, Word64Set)
+ GHC.Data.Word64Set.Internal: splitMember :: Key -> Word64Set -> (Word64Set, Bool, Word64Set)
+ GHC.Data.Word64Set.Internal: splitRoot :: Word64Set -> [Word64Set]
+ GHC.Data.Word64Set.Internal: suffixBitMask :: Word64
+ GHC.Data.Word64Set.Internal: takeWhileAntitone :: (Key -> Bool) -> Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: toAscList :: Word64Set -> [Key]
+ GHC.Data.Word64Set.Internal: toDescList :: Word64Set -> [Key]
+ GHC.Data.Word64Set.Internal: toList :: Word64Set -> [Key]
+ GHC.Data.Word64Set.Internal: type BitMap = Word64
+ GHC.Data.Word64Set.Internal: type Key = Word64
+ GHC.Data.Word64Set.Internal: type Mask = Word64
+ GHC.Data.Word64Set.Internal: type Prefix = Word64
+ GHC.Data.Word64Set.Internal: union :: Word64Set -> Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: unions :: Foldable f => f Word64Set -> Word64Set
+ GHC.Data.Word64Set.Internal: zero :: Word64 -> Mask -> Bool
+ GHC.Driver.CmdLine: Word64Suffix :: (Word64 -> EwM m ()) -> OptKind (m :: Type -> Type)
+ GHC.Runtime.Interpreter: [NewBreakModule] :: String -> Message (RemotePtr BreakModule)
+ GHC.Runtime.Interpreter: newModuleName :: Interp -> ModuleName -> IO (RemotePtr ModuleName)
+ GHC.Runtime.Interpreter.Process: [NewBreakModule] :: String -> Message (RemotePtr BreakModule)
+ GHC.StgToJS.Symbols: word64BS :: Word64 -> ByteString
+ GHC.Tc.Types: [env_ut] :: Env gbl lcl -> {-# UNPACK #-} !Char
+ GHC.Types.Unique: mkTag :: Char -> Word64
+ GHC.Types.Unique: mkUniqueInt :: Char -> Int -> Unique
+ GHC.Types.Unique: mkUniqueIntGrimily :: Int -> Unique
+ GHC.Types.Unique.Supply: uniqFromTag :: Char -> IO Unique
+ GHC.Utils.Containers.Internal.BitUtil: bitcount :: Int -> Word64 -> Int
+ GHC.Utils.Containers.Internal.BitUtil: highestBitMask :: Word64 -> Word64
+ GHC.Utils.Containers.Internal.BitUtil: shiftLL :: Word64 -> Int -> Word64
+ GHC.Utils.Containers.Internal.BitUtil: shiftRL :: Word64 -> Int -> Word64
+ GHC.Utils.Containers.Internal.StrictPair: (:*:) :: !a -> !b -> StrictPair a b
+ GHC.Utils.Containers.Internal.StrictPair: data StrictPair a b
+ GHC.Utils.Containers.Internal.StrictPair: infixr 1 :*:
+ GHC.Utils.Containers.Internal.StrictPair: toPair :: StrictPair a b -> (a, b)
+ GHC.Utils.Outputable: instance GHC.Utils.Outputable.Outputable GHC.Data.Word64Set.Internal.Word64Set
+ GHC.Utils.Outputable: word64 :: IsLine doc => Word64 -> doc
+ GHC.Utils.Unique: anyOfUnique :: Uniquable a => a -> [Unique] -> Bool
+ GHC.Utils.Unique: sameUnique :: Uniquable a => a -> a -> Bool
+ GHC.Utils.Word64: intToWord64 :: HasCallStack => Int -> Word64
+ GHC.Utils.Word64: truncateWord64ToWord32 :: Word64 -> Word32
+ GHC.Utils.Word64: word64ToInt :: HasCallStack => Word64 -> Int
- GHC: DynFlags :: GhcMode -> GhcLink -> !Backend -> {-# UNPACK #-} !GhcNameVersion -> {-# UNPACK #-} !FileSettings -> Platform -> {-# UNPACK #-} !ToolSettings -> {-# UNPACK #-} !PlatformMisc -> [(String, String)] -> TempDir -> Int -> Int -> Int -> Int -> Int -> Maybe String -> [Int] -> Maybe ParMakeCount -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> !Int -> Maybe Int -> Maybe Int -> Int -> Maybe Word -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Bool -> Maybe Int -> Int -> [FilePath] -> ModuleName -> Maybe String -> IntWithInf -> IntWithInf -> Int -> Int -> Int -> UnitId -> Maybe UnitId -> [(ModuleName, Module)] -> Maybe FilePath -> Maybe String -> Set ModuleName -> Set ModuleName -> Ways -> Maybe (String, Int) -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> String -> String -> String -> String -> String -> String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> DynLibLoader -> !Bool -> FilePath -> Maybe FilePath -> [Option] -> IncludeSpecs -> [String] -> [String] -> [String] -> Maybe String -> RtsOptsEnabled -> Bool -> String -> [ModuleName] -> [(ModuleName, String)] -> [String] -> [ExternalPluginSpec] -> FilePath -> Bool -> Bool -> [ModuleName] -> [String] -> [PackageDBFlag] -> [IgnorePackageFlag] -> [PackageFlag] -> [PackageFlag] -> [TrustFlag] -> Maybe FilePath -> EnumSet DumpFlag -> EnumSet GeneralFlag -> EnumSet WarningFlag -> EnumSet WarningFlag -> WarningCategorySet -> WarningCategorySet -> Maybe Language -> SafeHaskellMode -> Bool -> Bool -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> [OnOff Extension] -> EnumSet Extension -> !UnfoldingOpts -> Int -> Int -> FlushOut -> Maybe FilePath -> Maybe String -> [String] -> Int -> Int -> Bool -> OverridingBool -> Bool -> Scheme -> ProfAuto -> [CallerCcFilter] -> Maybe String -> Maybe SseVersion -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> IORef (Maybe LinkerInfo) -> IORef (Maybe CompilerInfo) -> IORef (Maybe CompilerInfo) -> Int -> Int -> Int -> Bool -> Maybe Int -> Word -> Int -> Weights -> DynFlags
+ GHC: DynFlags :: GhcMode -> GhcLink -> !Backend -> {-# UNPACK #-} !GhcNameVersion -> {-# UNPACK #-} !FileSettings -> Platform -> {-# UNPACK #-} !ToolSettings -> {-# UNPACK #-} !PlatformMisc -> [(String, String)] -> TempDir -> Int -> Int -> Int -> Int -> Int -> Maybe String -> [Int] -> Maybe ParMakeCount -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> !Int -> Maybe Int -> Maybe Int -> Int -> Maybe Word -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Bool -> Maybe Int -> Int -> [FilePath] -> ModuleName -> Maybe String -> IntWithInf -> IntWithInf -> Int -> Int -> Int -> UnitId -> Maybe UnitId -> [(ModuleName, Module)] -> Maybe FilePath -> Maybe String -> Set ModuleName -> Set ModuleName -> Ways -> Maybe (String, Int) -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> String -> String -> String -> String -> String -> String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> DynLibLoader -> !Bool -> FilePath -> Maybe FilePath -> [Option] -> IncludeSpecs -> [String] -> [String] -> [String] -> Maybe String -> RtsOptsEnabled -> Bool -> String -> [ModuleName] -> [(ModuleName, String)] -> [String] -> [ExternalPluginSpec] -> FilePath -> Bool -> Bool -> [ModuleName] -> [String] -> [PackageDBFlag] -> [IgnorePackageFlag] -> [PackageFlag] -> [PackageFlag] -> [TrustFlag] -> Maybe FilePath -> EnumSet DumpFlag -> EnumSet GeneralFlag -> EnumSet WarningFlag -> EnumSet WarningFlag -> WarningCategorySet -> WarningCategorySet -> Maybe Language -> SafeHaskellMode -> Bool -> Bool -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> [OnOff Extension] -> EnumSet Extension -> !UnfoldingOpts -> Int -> Int -> FlushOut -> Maybe FilePath -> Maybe String -> [String] -> Int -> Int -> Bool -> OverridingBool -> Bool -> Scheme -> ProfAuto -> [CallerCcFilter] -> Maybe String -> Maybe SseVersion -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> IORef (Maybe LinkerInfo) -> IORef (Maybe CompilerInfo) -> IORef (Maybe CompilerInfo) -> Int -> Int -> Int -> Bool -> Maybe Int -> Word64 -> Int -> Weights -> DynFlags
- GHC: ModBreaks :: ForeignRef BreakArray -> !Array BreakIndex SrcSpan -> !Array BreakIndex [OccName] -> !Array BreakIndex [String] -> !Array BreakIndex (RemotePtr CostCentre) -> IntMap CgBreakInfo -> ModBreaks
+ GHC: ModBreaks :: ForeignRef BreakArray -> !Array BreakIndex SrcSpan -> !Array BreakIndex [OccName] -> !Array BreakIndex [String] -> !Array BreakIndex (RemotePtr CostCentre) -> IntMap CgBreakInfo -> RemotePtr ModuleName -> ModBreaks
- GHC: [initialUnique] :: DynFlags -> Word
+ GHC: [initialUnique] :: DynFlags -> Word64
- GHC.ByteCode.Instr: BRK_FUN :: !Word16 -> Unique -> RemotePtr CostCentre -> BCInstr
+ GHC.ByteCode.Instr: BRK_FUN :: !Word16 -> RemotePtr ModuleName -> RemotePtr CostCentre -> BCInstr
- GHC.ByteCode.Types: ModBreaks :: ForeignRef BreakArray -> !Array BreakIndex SrcSpan -> !Array BreakIndex [OccName] -> !Array BreakIndex [String] -> !Array BreakIndex (RemotePtr CostCentre) -> IntMap CgBreakInfo -> ModBreaks
+ GHC.ByteCode.Types: ModBreaks :: ForeignRef BreakArray -> !Array BreakIndex SrcSpan -> !Array BreakIndex [OccName] -> !Array BreakIndex [String] -> !Array BreakIndex (RemotePtr CostCentre) -> IntMap CgBreakInfo -> RemotePtr ModuleName -> ModBreaks
- GHC.Cmm.Dataflow.Label: mkHooplLabel :: Int -> Label
+ GHC.Cmm.Dataflow.Label: mkHooplLabel :: Word64 -> Label
- GHC.Cmm.LRegSet: elemsLRegSet :: IntSet -> [Int]
+ GHC.Cmm.LRegSet: elemsLRegSet :: Word64Set -> [Word64]
- GHC.Cmm.LRegSet: plusLRegSet :: IntSet -> IntSet -> IntSet
+ GHC.Cmm.LRegSet: plusLRegSet :: Word64Set -> Word64Set -> Word64Set
- GHC.Cmm.LRegSet: sizeLRegSet :: IntSet -> Int
+ GHC.Cmm.LRegSet: sizeLRegSet :: Word64Set -> Int
- GHC.Cmm.LRegSet: type LRegKey = Int
+ GHC.Cmm.LRegSet: type LRegKey = Word64
- GHC.Cmm.LRegSet: type LRegSet = IntSet
+ GHC.Cmm.LRegSet: type LRegSet = Word64Set
- GHC.CmmToAsm.CFG.Dominators: type Graph = IntMap IntSet
+ GHC.CmmToAsm.CFG.Dominators: type Graph = Word64Map Word64Set
- GHC.CmmToAsm.CFG.Dominators: type Node = Int
+ GHC.CmmToAsm.CFG.Dominators: type Node = Word64
- GHC.Driver.DynFlags: DynFlags :: GhcMode -> GhcLink -> !Backend -> {-# UNPACK #-} !GhcNameVersion -> {-# UNPACK #-} !FileSettings -> Platform -> {-# UNPACK #-} !ToolSettings -> {-# UNPACK #-} !PlatformMisc -> [(String, String)] -> TempDir -> Int -> Int -> Int -> Int -> Int -> Maybe String -> [Int] -> Maybe ParMakeCount -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> !Int -> Maybe Int -> Maybe Int -> Int -> Maybe Word -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Bool -> Maybe Int -> Int -> [FilePath] -> ModuleName -> Maybe String -> IntWithInf -> IntWithInf -> Int -> Int -> Int -> UnitId -> Maybe UnitId -> [(ModuleName, Module)] -> Maybe FilePath -> Maybe String -> Set ModuleName -> Set ModuleName -> Ways -> Maybe (String, Int) -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> String -> String -> String -> String -> String -> String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> DynLibLoader -> !Bool -> FilePath -> Maybe FilePath -> [Option] -> IncludeSpecs -> [String] -> [String] -> [String] -> Maybe String -> RtsOptsEnabled -> Bool -> String -> [ModuleName] -> [(ModuleName, String)] -> [String] -> [ExternalPluginSpec] -> FilePath -> Bool -> Bool -> [ModuleName] -> [String] -> [PackageDBFlag] -> [IgnorePackageFlag] -> [PackageFlag] -> [PackageFlag] -> [TrustFlag] -> Maybe FilePath -> EnumSet DumpFlag -> EnumSet GeneralFlag -> EnumSet WarningFlag -> EnumSet WarningFlag -> WarningCategorySet -> WarningCategorySet -> Maybe Language -> SafeHaskellMode -> Bool -> Bool -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> [OnOff Extension] -> EnumSet Extension -> !UnfoldingOpts -> Int -> Int -> FlushOut -> Maybe FilePath -> Maybe String -> [String] -> Int -> Int -> Bool -> OverridingBool -> Bool -> Scheme -> ProfAuto -> [CallerCcFilter] -> Maybe String -> Maybe SseVersion -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> IORef (Maybe LinkerInfo) -> IORef (Maybe CompilerInfo) -> IORef (Maybe CompilerInfo) -> Int -> Int -> Int -> Bool -> Maybe Int -> Word -> Int -> Weights -> DynFlags
+ GHC.Driver.DynFlags: DynFlags :: GhcMode -> GhcLink -> !Backend -> {-# UNPACK #-} !GhcNameVersion -> {-# UNPACK #-} !FileSettings -> Platform -> {-# UNPACK #-} !ToolSettings -> {-# UNPACK #-} !PlatformMisc -> [(String, String)] -> TempDir -> Int -> Int -> Int -> Int -> Int -> Maybe String -> [Int] -> Maybe ParMakeCount -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> !Int -> Maybe Int -> Maybe Int -> Int -> Maybe Word -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Bool -> Maybe Int -> Int -> [FilePath] -> ModuleName -> Maybe String -> IntWithInf -> IntWithInf -> Int -> Int -> Int -> UnitId -> Maybe UnitId -> [(ModuleName, Module)] -> Maybe FilePath -> Maybe String -> Set ModuleName -> Set ModuleName -> Ways -> Maybe (String, Int) -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> String -> String -> String -> String -> String -> String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> DynLibLoader -> !Bool -> FilePath -> Maybe FilePath -> [Option] -> IncludeSpecs -> [String] -> [String] -> [String] -> Maybe String -> RtsOptsEnabled -> Bool -> String -> [ModuleName] -> [(ModuleName, String)] -> [String] -> [ExternalPluginSpec] -> FilePath -> Bool -> Bool -> [ModuleName] -> [String] -> [PackageDBFlag] -> [IgnorePackageFlag] -> [PackageFlag] -> [PackageFlag] -> [TrustFlag] -> Maybe FilePath -> EnumSet DumpFlag -> EnumSet GeneralFlag -> EnumSet WarningFlag -> EnumSet WarningFlag -> WarningCategorySet -> WarningCategorySet -> Maybe Language -> SafeHaskellMode -> Bool -> Bool -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> [OnOff Extension] -> EnumSet Extension -> !UnfoldingOpts -> Int -> Int -> FlushOut -> Maybe FilePath -> Maybe String -> [String] -> Int -> Int -> Bool -> OverridingBool -> Bool -> Scheme -> ProfAuto -> [CallerCcFilter] -> Maybe String -> Maybe SseVersion -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> IORef (Maybe LinkerInfo) -> IORef (Maybe CompilerInfo) -> IORef (Maybe CompilerInfo) -> Int -> Int -> Int -> Bool -> Maybe Int -> Word64 -> Int -> Weights -> DynFlags
- GHC.Driver.DynFlags: [initialUnique] :: DynFlags -> Word
+ GHC.Driver.DynFlags: [initialUnique] :: DynFlags -> Word64
- GHC.Driver.Session: DynFlags :: GhcMode -> GhcLink -> !Backend -> {-# UNPACK #-} !GhcNameVersion -> {-# UNPACK #-} !FileSettings -> Platform -> {-# UNPACK #-} !ToolSettings -> {-# UNPACK #-} !PlatformMisc -> [(String, String)] -> TempDir -> Int -> Int -> Int -> Int -> Int -> Maybe String -> [Int] -> Maybe ParMakeCount -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> !Int -> Maybe Int -> Maybe Int -> Int -> Maybe Word -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Bool -> Maybe Int -> Int -> [FilePath] -> ModuleName -> Maybe String -> IntWithInf -> IntWithInf -> Int -> Int -> Int -> UnitId -> Maybe UnitId -> [(ModuleName, Module)] -> Maybe FilePath -> Maybe String -> Set ModuleName -> Set ModuleName -> Ways -> Maybe (String, Int) -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> String -> String -> String -> String -> String -> String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> DynLibLoader -> !Bool -> FilePath -> Maybe FilePath -> [Option] -> IncludeSpecs -> [String] -> [String] -> [String] -> Maybe String -> RtsOptsEnabled -> Bool -> String -> [ModuleName] -> [(ModuleName, String)] -> [String] -> [ExternalPluginSpec] -> FilePath -> Bool -> Bool -> [ModuleName] -> [String] -> [PackageDBFlag] -> [IgnorePackageFlag] -> [PackageFlag] -> [PackageFlag] -> [TrustFlag] -> Maybe FilePath -> EnumSet DumpFlag -> EnumSet GeneralFlag -> EnumSet WarningFlag -> EnumSet WarningFlag -> WarningCategorySet -> WarningCategorySet -> Maybe Language -> SafeHaskellMode -> Bool -> Bool -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> [OnOff Extension] -> EnumSet Extension -> !UnfoldingOpts -> Int -> Int -> FlushOut -> Maybe FilePath -> Maybe String -> [String] -> Int -> Int -> Bool -> OverridingBool -> Bool -> Scheme -> ProfAuto -> [CallerCcFilter] -> Maybe String -> Maybe SseVersion -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> IORef (Maybe LinkerInfo) -> IORef (Maybe CompilerInfo) -> IORef (Maybe CompilerInfo) -> Int -> Int -> Int -> Bool -> Maybe Int -> Word -> Int -> Weights -> DynFlags
+ GHC.Driver.Session: DynFlags :: GhcMode -> GhcLink -> !Backend -> {-# UNPACK #-} !GhcNameVersion -> {-# UNPACK #-} !FileSettings -> Platform -> {-# UNPACK #-} !ToolSettings -> {-# UNPACK #-} !PlatformMisc -> [(String, String)] -> TempDir -> Int -> Int -> Int -> Int -> Int -> Maybe String -> [Int] -> Maybe ParMakeCount -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> !Int -> Maybe Int -> Maybe Int -> Int -> Maybe Word -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Bool -> Maybe Int -> Int -> [FilePath] -> ModuleName -> Maybe String -> IntWithInf -> IntWithInf -> Int -> Int -> Int -> UnitId -> Maybe UnitId -> [(ModuleName, Module)] -> Maybe FilePath -> Maybe String -> Set ModuleName -> Set ModuleName -> Ways -> Maybe (String, Int) -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> String -> String -> String -> String -> String -> String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> DynLibLoader -> !Bool -> FilePath -> Maybe FilePath -> [Option] -> IncludeSpecs -> [String] -> [String] -> [String] -> Maybe String -> RtsOptsEnabled -> Bool -> String -> [ModuleName] -> [(ModuleName, String)] -> [String] -> [ExternalPluginSpec] -> FilePath -> Bool -> Bool -> [ModuleName] -> [String] -> [PackageDBFlag] -> [IgnorePackageFlag] -> [PackageFlag] -> [PackageFlag] -> [TrustFlag] -> Maybe FilePath -> EnumSet DumpFlag -> EnumSet GeneralFlag -> EnumSet WarningFlag -> EnumSet WarningFlag -> WarningCategorySet -> WarningCategorySet -> Maybe Language -> SafeHaskellMode -> Bool -> Bool -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> [OnOff Extension] -> EnumSet Extension -> !UnfoldingOpts -> Int -> Int -> FlushOut -> Maybe FilePath -> Maybe String -> [String] -> Int -> Int -> Bool -> OverridingBool -> Bool -> Scheme -> ProfAuto -> [CallerCcFilter] -> Maybe String -> Maybe SseVersion -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> IORef (Maybe LinkerInfo) -> IORef (Maybe CompilerInfo) -> IORef (Maybe CompilerInfo) -> Int -> Int -> Int -> Bool -> Maybe Int -> Word64 -> Int -> Weights -> DynFlags
- GHC.Driver.Session: [initialUnique] :: DynFlags -> Word
+ GHC.Driver.Session: [initialUnique] :: DynFlags -> Word64
- GHC.Runtime.Interpreter: EvalBreak :: Bool -> HValueRef -> Int -> Int -> RemoteRef (ResumeContext b) -> RemotePtr CostCentreStack -> EvalStatus_ a b
+ GHC.Runtime.Interpreter: EvalBreak :: Bool -> HValueRef -> Int -> String -> RemoteRef (ResumeContext b) -> RemotePtr CostCentreStack -> EvalStatus_ a b
- GHC.StgToJS.Types: IdKey :: !Int -> !Int -> !IdType -> IdKey
+ GHC.StgToJS.Types: IdKey :: !Word64 -> !Int -> !IdType -> IdKey
- GHC.Types.Unique: getKey :: Unique -> Int
+ GHC.Types.Unique: getKey :: Unique -> Word64
- GHC.Types.Unique: mkLocalUnique :: Int -> Unique
+ GHC.Types.Unique: mkLocalUnique :: Word64 -> Unique
- GHC.Types.Unique: mkUnique :: Char -> Int -> Unique
+ GHC.Types.Unique: mkUnique :: Char -> Word64 -> Unique
- GHC.Types.Unique: mkUniqueGrimily :: Int -> Unique
+ GHC.Types.Unique: mkUniqueGrimily :: Word64 -> Unique
- GHC.Types.Unique: stepUnique :: Unique -> Int -> Unique
+ GHC.Types.Unique: stepUnique :: Unique -> Word64 -> Unique
- GHC.Types.Unique: unpkUnique :: Unique -> (Char, Int)
+ GHC.Types.Unique: unpkUnique :: Unique -> (Char, Word64)
- GHC.Types.Unique.DFM: udfmRestrictKeysSet :: UniqDFM key elt -> IntSet -> UniqDFM key elt
+ GHC.Types.Unique.DFM: udfmRestrictKeysSet :: UniqDFM key elt -> Word64Set -> UniqDFM key elt
- GHC.Types.Unique.FM: ufmToIntMap :: UniqFM key elt -> IntMap elt
+ GHC.Types.Unique.FM: ufmToIntMap :: UniqFM key elt -> Word64Map elt
- GHC.Types.Unique.FM: ufmToSet_Directly :: UniqFM key elt -> IntSet
+ GHC.Types.Unique.FM: ufmToSet_Directly :: UniqFM key elt -> Word64Set
- GHC.Types.Unique.FM: unsafeIntMapToUFM :: IntMap elt -> UniqFM key elt
+ GHC.Types.Unique.FM: unsafeIntMapToUFM :: Word64Map elt -> UniqFM key elt
- GHC.Types.Unique.Supply: initUniqSupply :: Word -> Int -> IO ()
+ GHC.Types.Unique.Supply: initUniqSupply :: Word64 -> Int -> IO ()

Files

GHC/Builtin/Uniques.hs view
@@ -66,8 +66,10 @@  import GHC.Utils.Outputable import GHC.Utils.Panic+import GHC.Utils.Panic.Plain (assert)  import Data.Maybe+import GHC.Utils.Word64 (word64ToInt)  -- | Get the 'Name' associated with a known-key 'Unique'. knownUniqueName :: Unique -> Maybe Name@@ -83,7 +85,9 @@       'm' -> Just $ getCTupleDataConName n       _   -> Nothing   where-    (tag, n) = unpkUnique u+    (tag, n') = unpkUnique u+    -- Known unique names are guaranteed to fit in Int, so we don't need the whole Word64.+    n = assert (isValidKnownKeyUnique u) (word64ToInt n')  {- Note [Unique layout for unboxed sums]@@ -115,14 +119,14 @@     assertPpr (arity <= 0x3f) (ppr arity) $               -- 0x3f since we only have 6 bits to encode the               -- alternative-    mkUnique 'z' (arity `shiftL` 8 .|. 0xfc)+    mkUniqueInt 'z' (arity `shiftL` 8 .|. 0xfc)  mkSumDataConUnique :: ConTagZ -> Arity -> Unique mkSumDataConUnique alt arity   | alt >= arity   = panic ("mkSumDataConUnique: " ++ show alt ++ " >= " ++ show arity)   | otherwise-  = mkUnique 'z' (arity `shiftL` 8 + alt `shiftL` 2) {- skip the tycon -}+  = mkUniqueInt 'z' (arity `shiftL` 8 + alt `shiftL` 2) {- skip the tycon -}  getUnboxedSumName :: Int -> Name getUnboxedSumName n@@ -209,17 +213,17 @@ -}  mkCTupleTyConUnique :: Arity -> Unique-mkCTupleTyConUnique a = mkUnique 'k' (2*a)+mkCTupleTyConUnique a = mkUniqueInt 'k' (2*a)  mkCTupleDataConUnique :: Arity -> Unique-mkCTupleDataConUnique a = mkUnique 'm' (3*a)+mkCTupleDataConUnique a = mkUniqueInt 'm' (3*a)  mkCTupleSelIdUnique :: ConTagZ -> Arity -> Unique mkCTupleSelIdUnique sc_pos arity   | sc_pos >= arity   = panic ("mkCTupleSelIdUnique: " ++ show sc_pos ++ " >= " ++ show arity)   | otherwise-  = mkUnique 'j' (arity `shiftL` cTupleSelIdArityBits + sc_pos)+  = mkUniqueInt 'j' (arity `shiftL` cTupleSelIdArityBits + sc_pos)  getCTupleTyConName :: Int -> Name getCTupleTyConName n =@@ -262,12 +266,12 @@ -- Normal tuples  mkTupleDataConUnique :: Boxity -> Arity -> Unique-mkTupleDataConUnique Boxed          a = mkUnique '7' (3*a)    -- may be used in C labels-mkTupleDataConUnique Unboxed        a = mkUnique '8' (3*a)+mkTupleDataConUnique Boxed          a = mkUniqueInt '7' (3*a)    -- may be used in C labels+mkTupleDataConUnique Unboxed        a = mkUniqueInt '8' (3*a)  mkTupleTyConUnique :: Boxity -> Arity -> Unique-mkTupleTyConUnique Boxed           a  = mkUnique '4' (2*a)-mkTupleTyConUnique Unboxed         a  = mkUnique '5' (2*a)+mkTupleTyConUnique Boxed           a  = mkUniqueInt '4' (2*a)+mkTupleTyConUnique Unboxed         a  = mkUniqueInt '5' (2*a)  -- | This function is an inverse of `mkTupleTyConUnique` isTupleTyConUnique :: Unique -> Maybe (Boxity, Arity)@@ -278,7 +282,8 @@     _        -> Nothing   where     (tag,   n) = unpkUnique u-    (arity, i) = quotRem n 2+    (arity', i) = quotRem n 2+    arity = word64ToInt arity'  getTupleTyConName :: Boxity -> Int -> Name getTupleTyConName boxity n =@@ -298,7 +303,7 @@       _          -> panic "getTupleDataConName: impossible"  {--Note [Uniques for wired-in prelude things and known masks]+Note [Uniques for wired-in prelude things and known tags] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Allocation of unique supply characters:         v,u: for renumbering value-, and usage- vars.@@ -358,27 +363,27 @@ mkPrimOpWrapperUnique  :: Int -> Unique mkPreludeMiscIdUnique  :: Int -> Unique -mkAlphaTyVarUnique   i = mkUnique '1' i-mkPreludeClassUnique i = mkUnique '2' i+mkAlphaTyVarUnique   i = mkUniqueInt '1' i+mkPreludeClassUnique i = mkUniqueInt '2' i  ---------------------------------------------------mkPrimOpIdUnique op         = mkUnique '9' (2*op)-mkPrimOpWrapperUnique op    = mkUnique '9' (2*op+1)-mkPreludeMiscIdUnique  i    = mkUnique '0' i+mkPrimOpIdUnique op         = mkUniqueInt '9' (2*op)+mkPrimOpWrapperUnique op    = mkUniqueInt '9' (2*op+1)+mkPreludeMiscIdUnique  i    = mkUniqueInt '0' i  mkPseudoUniqueE, mkBuiltinUnique :: Int -> Unique -mkBuiltinUnique i = mkUnique 'B' i-mkPseudoUniqueE i = mkUnique 'E' i -- used in NCG spiller to create spill VirtualRegs+mkBuiltinUnique i = mkUniqueInt 'B' i+mkPseudoUniqueE i = mkUniqueInt 'E' i -- used in NCG spiller to create spill VirtualRegs  mkRegSingleUnique, mkRegPairUnique, mkRegSubUnique, mkRegClassUnique :: Int -> Unique-mkRegSingleUnique = mkUnique 'R'-mkRegSubUnique    = mkUnique 'S'-mkRegPairUnique   = mkUnique 'P'-mkRegClassUnique  = mkUnique 'L'+mkRegSingleUnique = mkUniqueInt 'R'+mkRegSubUnique    = mkUniqueInt 'S'+mkRegPairUnique   = mkUniqueInt 'P'+mkRegClassUnique  = mkUniqueInt 'L'  mkCostCentreUnique :: Int -> Unique-mkCostCentreUnique = mkUnique 'C'+mkCostCentreUnique = mkUniqueInt 'C'  varNSUnique, dataNSUnique, tvNSUnique, tcNSUnique :: Unique varNSUnique    = mkUnique 'i' 0@@ -387,7 +392,7 @@ tcNSUnique     = mkUnique 'c' 0  mkFldNSUnique :: FastString -> Unique-mkFldNSUnique fs = mkUnique 'f' (uniqueOfFS fs)+mkFldNSUnique fs = mkUniqueInt 'f' (uniqueOfFS fs)  isFldNSUnique :: Unique -> Bool isFldNSUnique uniq = case unpkUnique uniq of@@ -401,7 +406,7 @@ -- See Note [Related uniques for wired-in things]  mkPreludeTyConUnique   :: Int -> Unique-mkPreludeTyConUnique i = mkUnique '3' (2*i)+mkPreludeTyConUnique i = mkUniqueInt '3' (2*i)  tyConRepNameUnique :: Unique -> Unique tyConRepNameUnique  u = incrUnique u@@ -411,7 +416,7 @@ -- See Note [Related uniques for wired-in things]  mkPreludeDataConUnique :: Int -> Unique-mkPreludeDataConUnique i = mkUnique '6' (3*i)    -- Must be alphabetic+mkPreludeDataConUnique i = mkUniqueInt '6' (3*i)    -- Must be alphabetic  dataConTyRepNameUnique, dataConWorkerUnique :: Unique -> Unique dataConWorkerUnique  u = incrUnique u@@ -437,7 +442,7 @@ -- A little delicate!  mkBoxingTyConUnique :: Int -> Unique-mkBoxingTyConUnique i = mkUnique 'b' (5*i)+mkBoxingTyConUnique i = mkUniqueInt 'b' (5*i)  boxingDataConUnique :: Unique -> Unique boxingDataConUnique u = stepUnique u 2
GHC/Builtin/primops.txt.pp view
@@ -2535,18 +2535,45 @@ section "Exceptions" ------------------------------------------------------------------------ --- Note [Strictness for mask/unmask/catch]--- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- Note [Strict IO wrappers]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~ -- Consider this example, which comes from GHC.IO.Handle.Internals:---    wantReadableHandle3 f ma b st+--    wantReadableHandle3 f mv b st --      = case ... of---          DEFAULT -> case ma of MVar a -> ...---          0#      -> maskAsyncExceptions# (\st -> case ma of MVar a -> ...)+--          DEFAULT -> case mv of MVar a -> ...+--          0#      -> maskAsyncExceptions# (\st -> case mv of MVar a -> ...) -- The outer case just decides whether to mask exceptions, but we don't want--- thereby to hide the strictness in 'ma'!  Hence the use of strictOnceApply1Dmd--- in mask and unmask. But catch really is lazy in its first argument, see--- #11555. So for IO actions 'ma' we often use a wrapper around it that is--- head-strict in 'ma': GHC.IO.catchException.+-- thereby to hide the strictness in `mv`!  Hence the use of strictOnceApply1Dmd+-- in mask#, unmask# and atomically# (where we use strictManyApply1Dmd to respect+-- that it potentially calls its action multiple times).+--+-- Note [Strictness for catch-style primops]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- The catch#-style primops always call their action, just like outlined+-- in Note [Strict IO wrappers].+-- However, it is important that we give their first arg lazyApply1Dmd and not+-- strictOnceApply1Dmd, like for mask#. Here is why. Consider a call+--+--   catch# act handler s+--+-- If `act = raiseIO# ...`, using strictOnceApply1Dmd for `act` would mean that+-- the call forwards the dead-end flag from `act` (see Note [Dead ends] and+-- Note [Precise exceptions and strictness analysis]).+-- This would cause dead code elimination to discard the continuation of the+-- catch# call, among other things. This first came up in #11555.+--+-- Hence catch# uses lazyApply1Dmd in order /not/ to forward the dead-end flag+-- from `act`. (This is a bit brutal, but the language of strictness types is+-- not expressive enough to give it a more precise semantics that is still+-- sound.)+-- For perf reasons we often (but not always) choose to use a wrapper around+-- catch# that is head-strict in `act`: GHC.IO.catchException.+--+-- A similar caveat applies to prompt#, which can be seen as a+-- generalisation of catch# as explained in GHC.Prim#continuations#.+-- The reason is that even if `act` appears dead-ending (e.g., looping)+-- `prompt# tag ma s` might return alright due to a (higher-order) use of+-- `control0#` in `act`. This came up in #25439.  primop  CatchOp "catch#" GenPrimOp           (State# RealWorld -> (# State# RealWorld, o #) )@@ -2563,7 +2590,7 @@    strictness  = { \ _arity -> mkClosedDmdSig [ lazyApply1Dmd                                                  , lazyApply2Dmd                                                  , topDmd] topDiv }-                 -- See Note [Strictness for mask/unmask/catch]+                 -- See Note [Strictness for catch-style primops]    out_of_line = True    has_side_effects = True @@ -2628,7 +2655,7 @@      in continuation-style primops\" for details. }    with    strictness  = { \ _arity -> mkClosedDmdSig [strictOnceApply1Dmd,topDmd] topDiv }-                 -- See Note [Strictness for mask/unmask/catch]+                 -- See Note [Strict IO wrappers]    out_of_line = True    has_side_effects = True @@ -2643,6 +2670,7 @@      in continuation-style primops\" for details. }    with    strictness  = { \ _arity -> mkClosedDmdSig [strictOnceApply1Dmd,topDmd] topDiv }+                 -- See Note [Strict IO wrappers]    out_of_line = True    has_side_effects = True @@ -2657,7 +2685,7 @@      in continuation-style primops\" for details. }    with    strictness  = { \ _arity -> mkClosedDmdSig [strictOnceApply1Dmd,topDmd] topDiv }-                 -- See Note [Strictness for mask/unmask/catch]+                 -- See Note [Strict IO wrappers]    out_of_line = True    has_side_effects = True @@ -2843,7 +2871,8 @@      -> State# RealWorld -> (# State# RealWorld, a #)    { See "GHC.Prim#continuations". }    with-   strictness = { \ _arity -> mkClosedDmdSig [topDmd, strictOnceApply1Dmd, topDmd] topDiv }+   strictness = { \ _arity -> mkClosedDmdSig [topDmd, lazyApply1Dmd, topDmd] topDiv }+                 -- See Note [Strictness for catch-style primops]    out_of_line = True    has_side_effects = True @@ -2870,7 +2899,7 @@    -> State# RealWorld -> (# State# RealWorld, v #)    with    strictness  = { \ _arity -> mkClosedDmdSig [strictManyApply1Dmd,topDmd] topDiv }-                 -- See Note [Strictness for mask/unmask/catch]+                 -- See Note [Strict IO wrappers]    out_of_line = True    has_side_effects = True @@ -2899,7 +2928,7 @@    strictness  = { \ _arity -> mkClosedDmdSig [ lazyApply1Dmd                                                  , lazyApply1Dmd                                                  , topDmd ] topDiv }-                 -- See Note [Strictness for mask/unmask/catch]+                 -- See Note [Strictness for catch-style primops]    out_of_line = True    has_side_effects = True @@ -2911,7 +2940,7 @@    strictness  = { \ _arity -> mkClosedDmdSig [ lazyApply1Dmd                                                  , lazyApply2Dmd                                                  , topDmd ] topDiv }-                 -- See Note [Strictness for mask/unmask/catch]+                 -- See Note [Strictness for catch-style primops]    out_of_line = True    has_side_effects = True @@ -3586,6 +3615,7 @@    with    out_of_line = True    strictness = { \ _arity -> mkClosedDmdSig [topDmd, topDmd, strictOnceApply1Dmd] topDiv }+                 -- See Note [Strict IO wrappers]   ------------------------------------------------------------------------
GHC/ByteCode/Asm.hs view
@@ -27,7 +27,6 @@ import GHC.Types.Name import GHC.Types.Name.Set import GHC.Types.Literal-import GHC.Types.Unique import GHC.Types.Unique.DSet  import GHC.Utils.Outputable@@ -518,11 +517,11 @@   CCALL off m_addr i       -> do np <- addr m_addr                                  emit bci_CCALL [wOp off, Op np, SmallOp i]   PRIMCALL                 -> emit bci_PRIMCALL []-  BRK_FUN index uniq cc    -> do p1 <- ptr BCOPtrBreakArray-                                 q <- int (getKey uniq)+  BRK_FUN index mod cc     -> do p1 <- ptr BCOPtrBreakArray+                                 m <- addr mod                                  np <- addr cc                                  emit bci_BRK_FUN [Op p1, SmallOp index,-                                                   Op q, Op np]+                                                   Op m, Op np]    where     literal (LitLabel fs (Just sz) _)
GHC/ByteCode/Instr.hs view
@@ -19,7 +19,6 @@ import GHC.StgToCmm.Layout     ( ArgRep(..) ) import GHC.Utils.Outputable import GHC.Types.Name-import GHC.Types.Unique import GHC.Types.Literal import GHC.Core.DataCon import GHC.Builtin.PrimOps@@ -31,6 +30,7 @@ import GHC.Stack.CCS (CostCentre)  import GHC.Stg.Syntax+import Language.Haskell.Syntax.Module.Name (ModuleName)  -- ---------------------------------------------------------------------------- -- Bytecode instructions@@ -205,7 +205,7 @@                    -- Note [unboxed tuple bytecodes and tuple_BCO] in GHC.StgToByteCode     -- Breakpoints-   | BRK_FUN         !Word16 Unique (RemotePtr CostCentre)+   | BRK_FUN         !Word16 (RemotePtr ModuleName) (RemotePtr CostCentre)  -- ----------------------------------------------------------------------------- -- Printing bytecode instructions@@ -356,11 +356,7 @@    ppr ENTER                 = text "ENTER"    ppr (RETURN pk)           = text "RETURN  " <+> ppr pk    ppr (RETURN_TUPLE)        = text "RETURN_TUPLE"-   ppr (BRK_FUN index uniq _cc) = text "BRK_FUN" <+> ppr index <+> mb_uniq <+> text "<cc>"-     where mb_uniq = sdocOption sdocSuppressUniques $ \case-             True  -> text "<uniq>"-             False -> ppr uniq-+   ppr (BRK_FUN index _mod_name _cc) = text "BRK_FUN" <+> ppr index <+> text "<module>" <+> text "<cc>"   -- -----------------------------------------------------------------------------
GHC/ByteCode/Types.hs view
@@ -44,6 +44,7 @@ import GHC.Stack.CCS import GHC.Cmm.Expr ( GlobalRegSet, emptyRegSet, regSetToList ) import GHC.Iface.Syntax+import Language.Haskell.Syntax.Module.Name (ModuleName)  -- ----------------------------------------------------------------------------- -- Compiled Byte Code@@ -242,6 +243,7 @@         -- ^ Array pointing to cost centre for each breakpoint    , modBreaks_breakInfo :: IntMap CgBreakInfo         -- ^ info about each breakpoint from the bytecode generator+   , modBreaks_module :: RemotePtr ModuleName    }  seqModBreaks :: ModBreaks -> ()@@ -251,7 +253,8 @@   rnf modBreaks_vars `seq`   rnf modBreaks_decls `seq`   rnf modBreaks_ccs `seq`-  rnf (fmap seqCgBreakInfo modBreaks_breakInfo)+  rnf (fmap seqCgBreakInfo modBreaks_breakInfo) `seq`+  rnf modBreaks_module  -- | Construct an empty ModBreaks emptyModBreaks :: ModBreaks@@ -263,6 +266,7 @@    , modBreaks_decls = array (0,-1) []    , modBreaks_ccs = array (0,-1) []    , modBreaks_breakInfo = IntMap.empty+   , modBreaks_module = toRemotePtr nullPtr    }  {-
GHC/Cmm/CommonBlockElim.hs view
@@ -26,6 +26,7 @@ import qualified GHC.Data.TrieMap as TM import GHC.Types.Unique.FM import GHC.Types.Unique+import GHC.Utils.Word64 (truncateWord64ToWord32) import Control.Arrow (first, second) import Data.List.NonEmpty (NonEmpty (..)) import qualified Data.List.NonEmpty as NE@@ -182,8 +183,10 @@          cvt = fromInteger . toInteger +        -- Since we are hashing, we can savely downcast Word64 to Word32 here.+        -- Although a different hashing function may be more effective.         hash_unique :: Uniquable a => a -> Word32-        hash_unique = cvt . getKey . getUnique+        hash_unique = truncateWord64ToWord32 . getKey . getUnique  -- | Ignore these node types for equality dont_care :: CmmNode O x -> Bool
GHC/Cmm/Dataflow/Collections.hs view
@@ -12,10 +12,11 @@  import GHC.Prelude -import qualified Data.IntMap.Strict as M-import qualified Data.IntSet as S+import qualified GHC.Data.Word64Map.Strict as M+import qualified GHC.Data.Word64Set as S  import Data.List (foldl1')+import Data.Word (Word64)  class IsSet set where   type ElemOf set@@ -107,10 +108,10 @@ -- Basic instances ----------------------------------------------------------------------------- -newtype UniqueSet = US S.IntSet deriving (Eq, Ord, Show, Semigroup, Monoid)+newtype UniqueSet = US S.Word64Set deriving (Eq, Ord, Show, Semigroup, Monoid)  instance IsSet UniqueSet where-  type ElemOf UniqueSet = Int+  type ElemOf UniqueSet = Word64    setNull (US s) = S.null s   setSize (US s) = S.size s@@ -133,11 +134,11 @@   setElems (US s) = S.elems s   setFromList ks = US (S.fromList ks) -newtype UniqueMap v = UM (M.IntMap v)+newtype UniqueMap v = UM (M.Word64Map v)   deriving (Eq, Ord, Show, Functor, Foldable, Traversable)  instance IsMap UniqueMap where-  type KeyOf UniqueMap = Int+  type KeyOf UniqueMap = Word64    mapNull (UM m) = M.null m   mapSize (UM m) = M.size m
GHC/Cmm/Dataflow/Label.hs view
@@ -20,25 +20,26 @@ -- TODO: This should really just use GHC's Unique and Uniq{Set,FM} import GHC.Cmm.Dataflow.Collections -import GHC.Types.Unique (Uniquable(..))+import GHC.Types.Unique (Uniquable(..), mkUniqueGrimily) import GHC.Data.TrieMap+import Data.Word (Word64)   ----------------------------------------------------------------------------- --              Label ----------------------------------------------------------------------------- -newtype Label = Label { lblToUnique :: Int }+newtype Label = Label { lblToUnique :: Word64 }   deriving (Eq, Ord) -mkHooplLabel :: Int -> Label+mkHooplLabel :: Word64 -> Label mkHooplLabel = Label  instance Show Label where   show (Label n) = "L" ++ show n  instance Uniquable Label where-  getUnique label = getUnique (lblToUnique label)+  getUnique label = mkUniqueGrimily (lblToUnique label)  instance Outputable Label where   ppr label = ppr (getUnique label)
GHC/Cmm/Dominators.hs view
@@ -26,8 +26,7 @@ import Data.Foldable() import qualified Data.Tree as Tree -import qualified Data.IntMap.Strict as IM-import qualified Data.IntSet as IS+import Data.Word  import qualified GHC.CmmToAsm.CFG.Dominators as LT @@ -41,6 +40,9 @@ import GHC.Utils.Outputable( Outputable(..), text, int, hcat, (<+>)) import GHC.Utils.Misc import GHC.Utils.Panic+import GHC.Utils.Word64 (intToWord64)+import qualified GHC.Data.Word64Map as WM+import qualified GHC.Data.Word64Set as WS   -- | =Dominator sets@@ -129,33 +131,37 @@ -- The implementation uses the Lengauer-Tarjan algorithm from the x86 -- back end. +-- Technically, we do not need Word64 here, however the dominators code+-- has to accomodate Word64 for other uses.+ graphWithDominators g = GraphWithDominators (reachable rpblocks g) dmap rpmap       where rpblocks = revPostorderFrom (graphMap g) (g_entry g)             rplabels' = map entryLabel rpblocks-            rplabels :: Array Int Label+            rplabels :: Array Word64 Label             rplabels = listArray bounds rplabels'              rpmap :: LabelMap RPNum             rpmap = mapFromList $ zipWith kvpair rpblocks [0..]               where kvpair block i = (entryLabel block, RPNum i) -            labelIndex :: Label -> Int+            labelIndex :: Label -> Word64             labelIndex = flip findLabelIn imap-              where imap :: LabelMap Int+              where imap :: LabelMap Word64                     imap = mapFromList $ zip rplabels' [0..]             blockIndex = labelIndex . entryLabel -            bounds = (0, length rpblocks - 1)+            bounds :: (Word64, Word64)+            bounds = (0, intToWord64 (length rpblocks - 1))              ltGraph :: [Block node C C] -> LT.Graph-            ltGraph [] = IM.empty+            ltGraph [] = WM.empty             ltGraph (block:blocks) =-                IM.insert+                WM.insert                       (blockIndex block)-                      (IS.fromList $ map labelIndex $ successors block)+                      (WS.fromList $ map labelIndex $ successors block)                       (ltGraph blocks) -            idom_array :: Array Int LT.Node+            idom_array :: Array Word64 LT.Node             idom_array = array bounds $ LT.idom (0, ltGraph rpblocks)              domSet 0 = EntryNode
GHC/Cmm/LRegSet.hs view
@@ -20,34 +20,35 @@ import GHC.Prelude import GHC.Types.Unique import GHC.Cmm.Expr+import GHC.Word -import Data.IntSet as IntSet+import GHC.Data.Word64Set as Word64Set  -- Compact sets for membership tests of local variables. -type LRegSet = IntSet.IntSet-type LRegKey = Int+type LRegSet = Word64Set.Word64Set+type LRegKey = Word64  emptyLRegSet :: LRegSet-emptyLRegSet = IntSet.empty+emptyLRegSet = Word64Set.empty  nullLRegSet :: LRegSet -> Bool-nullLRegSet = IntSet.null+nullLRegSet = Word64Set.null  insertLRegSet :: LocalReg -> LRegSet -> LRegSet-insertLRegSet l = IntSet.insert (getKey (getUnique l))+insertLRegSet l = Word64Set.insert (getKey (getUnique l))  elemLRegSet :: LocalReg -> LRegSet -> Bool-elemLRegSet l = IntSet.member (getKey (getUnique l))+elemLRegSet l = Word64Set.member (getKey (getUnique l))  deleteFromLRegSet :: LRegSet -> LocalReg -> LRegSet-deleteFromLRegSet set reg = IntSet.delete (getKey . getUnique $ reg) set+deleteFromLRegSet set reg = Word64Set.delete (getKey . getUnique $ reg) set -sizeLRegSet :: IntSet -> Int-sizeLRegSet = IntSet.size+sizeLRegSet :: Word64Set -> Int+sizeLRegSet = Word64Set.size -plusLRegSet :: IntSet -> IntSet -> IntSet-plusLRegSet = IntSet.union+plusLRegSet :: Word64Set -> Word64Set -> Word64Set+plusLRegSet = Word64Set.union -elemsLRegSet :: IntSet -> [Int]-elemsLRegSet = IntSet.toList+elemsLRegSet :: Word64Set -> [Word64]+elemsLRegSet = Word64Set.toList
GHC/Cmm/Lexer.hs view
@@ -1,7 +1,7 @@ {-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-missing-signatures #-} {-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-}-{-# LINE 13 "_build/source-dist/ghc-9.8.3-src/ghc-9.8.3/compiler/GHC/Cmm/Lexer.x" #-}+{-# LINE 13 "_build/source-dist/ghc-9.8.4-src/ghc-9.8.4/compiler/GHC/Cmm/Lexer.x" #-} module GHC.Cmm.Lexer (    CmmToken(..), cmmlex,   ) where@@ -386,7 +386,7 @@   , (0,alex_action_20)   ] -{-# LINE 134 "_build/source-dist/ghc-9.8.3-src/ghc-9.8.3/compiler/GHC/Cmm/Lexer.x" #-}+{-# LINE 134 "_build/source-dist/ghc-9.8.4-src/ghc-9.8.4/compiler/GHC/Cmm/Lexer.x" #-} data CmmToken   = CmmT_SpecChar  Char   | CmmT_DotDot
GHC/Cmm/Sink.hs view
@@ -21,7 +21,7 @@ import GHC.Platform import GHC.Types.Unique.FM -import qualified Data.IntSet as IntSet+import qualified GHC.Data.Word64Set as Word64Set import Data.List (partition) import Data.Maybe @@ -175,7 +175,7 @@       -- Annotate the middle nodes with the registers live *after*       -- the node.  This will help us decide whether we can inline       -- an assignment in the current node or not.-      live = IntSet.unions (map getLive succs)+      live = Word64Set.unions (map getLive succs)       live_middle = gen_killL platform last live       ann_middles = annotate platform live_middle (blockToList middle) @@ -188,7 +188,7 @@       -- one predecessor), so identify the join points and the set       -- of registers live in them.       (joins, nonjoins) = partition (`mapMember` join_pts) succs-      live_in_joins = IntSet.unions (map getLive joins)+      live_in_joins = Word64Set.unions (map getLive joins)        -- We do not want to sink an assignment into multiple branches,       -- so identify the set of registers live in multiple successors.@@ -215,7 +215,7 @@             live_sets' | should_drop = live_sets                        | otherwise   = map upd live_sets -            upd set | r `elemLRegSet` set = set `IntSet.union` live_rhs+            upd set | r `elemLRegSet` set = set `Word64Set.union` live_rhs                     | otherwise          = set              live_rhs = foldRegsUsed platform (flip insertLRegSet) emptyLRegSet rhs
GHC/CmmToAsm/CFG.hs view
@@ -60,12 +60,16 @@ import GHC.Types.Unique import qualified GHC.CmmToAsm.CFG.Dominators as Dom import GHC.CmmToAsm.CFG.Weight+import GHC.Data.Word64Map.Strict (Word64Map)+import GHC.Data.Word64Set (Word64Set) import Data.IntMap.Strict (IntMap) import Data.IntSet (IntSet)  import qualified Data.IntMap.Strict as IM+import qualified GHC.Data.Word64Map.Strict as WM import qualified Data.Map as M import qualified Data.IntSet as IS+import qualified GHC.Data.Word64Set as WS import qualified Data.Set as S import Data.Tree import Data.Bifunctor@@ -90,6 +94,7 @@  import Control.Monad import GHC.Data.UnionFind+import Data.Word  type Prob = Double @@ -851,7 +856,7 @@      --TODO - This should be a no op: Export constructors? Use unsafeCoerce? ...     rooted = ( fromBlockId root-              , toIntMap $ fmap toIntSet graph) :: (Int, IntMap IntSet)+              , toWord64Map $ fmap toWord64Set graph) :: (Word64, Word64Map Word64Set)     tree = fmap toBlockId $ Dom.domTree rooted :: Tree BlockId      -- Map from Nodes to their dominators@@ -898,10 +903,10 @@           loopCount n = length $ nub . map fst . filter (setMember n . snd) $ bodies       in  map (\n -> (n, loopCount n)) $ nodes :: [(BlockId, Int)] -    toIntSet :: LabelSet -> IntSet-    toIntSet s = IS.fromList . map fromBlockId . setElems $ s-    toIntMap :: LabelMap a -> IntMap a-    toIntMap m = IM.fromList $ map (\(x,y) -> (fromBlockId x,y)) $ mapToList m+    toWord64Set :: LabelSet -> Word64Set+    toWord64Set s = WS.fromList . map fromBlockId . setElems $ s+    toWord64Map :: LabelMap a -> Word64Map a+    toWord64Map m = WM.fromList $ map (\(x,y) -> (fromBlockId x,y)) $ mapToList m      mkDomMap :: Tree BlockId -> LabelMap LabelSet     mkDomMap root = mapFromList $ go setEmpty root@@ -916,10 +921,10 @@                             (\n -> go (setInsert (rootLabel n) parents) n)                             leaves -    fromBlockId :: BlockId -> Int+    fromBlockId :: BlockId -> Word64     fromBlockId = getKey . getUnique -    toBlockId :: Int -> BlockId+    toBlockId :: Word64 -> BlockId     toBlockId = mkBlockId . mkUniqueGrimily  -- We make the CFG a Hoopl Graph, so we can reuse revPostOrder.
GHC/CmmToAsm/CFG/Dominators.hs view
@@ -21,8 +21,8 @@       /Advanced Compiler Design and Implementation/, 1997.      \[3\] Brisk, Sarrafzadeh,-      /Interference Graphs for Procedures in Static Single/-      /Information Form are Interval Graphs/, 2007.+      /Interference CGraphs for Procedures in Static Single/+      /Information Form are Interval CGraphs/, 2007.   * Strictness @@ -40,7 +40,7 @@   ,pddfs,rpddfs   ,fromAdj,fromEdges   ,toAdj,toEdges-  ,asTree,asGraph+  ,asTree,asCGraph   ,parents,ancestors ) where @@ -61,15 +61,24 @@ import Data.Array.Base   (unsafeNewArray_   ,unsafeWrite,unsafeRead)+import GHC.Data.Word64Set (Word64Set)+import qualified GHC.Data.Word64Set as WS+import GHC.Data.Word64Map (Word64Map)+import qualified GHC.Data.Word64Map as WM+import Data.Word  ----------------------------------------------------------------------------- -type Node       = Int-type Path       = [Node]-type Edge       = (Node,Node)-type Graph      = IntMap IntSet-type Rooted     = (Node, Graph)+-- Compacted nodes; these can be stored in contiguous arrays+type CNode       = Int+type CGraph      = IntMap IntSet +type Node     = Word64+type Path     = [Node]+type Edge     = (Node, Node)+type Graph    = Word64Map Word64Set+type Rooted   = (Node, Graph)+ -----------------------------------------------------------------------------  -- | /Dominators/.@@ -111,7 +120,7 @@ -- | /Immediate post-dominators/. -- Complexity as for @idom@. ipdom :: Rooted -> [(Node,Node)]-ipdom rg = runST (evalS idomM =<< initEnv (pruneReach (second predG rg)))+ipdom rg = runST (evalS idomM =<< initEnv (pruneReach (second predGW rg)))  ----------------------------------------------------------------------------- @@ -126,24 +135,24 @@ -----------------------------------------------------------------------------  type Dom s a = S s (Env s) a-type NodeSet    = IntSet-type NodeMap a  = IntMap a+type NodeSet    = Word64Set+type NodeMap a  = Word64Map a data Env s = Env-  {succE      :: !Graph-  ,predE      :: !Graph-  ,bucketE    :: !Graph+  {succE      :: !CGraph+  ,predE      :: !CGraph+  ,bucketE    :: !CGraph   ,dfsE       :: {-# UNPACK #-}!Int-  ,zeroE      :: {-# UNPACK #-}!Node-  ,rootE      :: {-# UNPACK #-}!Node-  ,labelE     :: {-# UNPACK #-}!(Arr s Node)-  ,parentE    :: {-# UNPACK #-}!(Arr s Node)-  ,ancestorE  :: {-# UNPACK #-}!(Arr s Node)-  ,childE     :: {-# UNPACK #-}!(Arr s Node)-  ,ndfsE      :: {-# UNPACK #-}!(Arr s Node)+  ,zeroE      :: {-# UNPACK #-}!CNode+  ,rootE      :: {-# UNPACK #-}!CNode+  ,labelE     :: {-# UNPACK #-}!(Arr s CNode)+  ,parentE    :: {-# UNPACK #-}!(Arr s CNode)+  ,ancestorE  :: {-# UNPACK #-}!(Arr s CNode)+  ,childE     :: {-# UNPACK #-}!(Arr s CNode)+  ,ndfsE      :: {-# UNPACK #-}!(Arr s CNode)   ,dfnE       :: {-# UNPACK #-}!(Arr s Int)   ,sdnoE      :: {-# UNPACK #-}!(Arr s Int)   ,sizeE      :: {-# UNPACK #-}!(Arr s Int)-  ,domE       :: {-# UNPACK #-}!(Arr s Node)+  ,domE       :: {-# UNPACK #-}!(Arr s CNode)   ,rnE        :: {-# UNPACK #-}!(Arr s Node)}  -----------------------------------------------------------------------------@@ -188,7 +197,7 @@  ----------------------------------------------------------------------------- -eval :: Node -> Dom s Node+eval :: CNode -> Dom s CNode eval v = do   n0 <- zeroM   a  <- ancestorM v@@ -205,7 +214,7 @@         True-> return l         False-> return la -compress :: Node -> Dom s ()+compress :: CNode -> Dom s () compress v = do   n0  <- zeroM   a   <- ancestorM v@@ -224,7 +233,7 @@  ----------------------------------------------------------------------------- -link :: Node -> Node -> Dom s ()+link :: CNode -> CNode -> Dom s () link v w = do   n0  <- zeroM   lw  <- labelM w@@ -268,7 +277,7 @@  ----------------------------------------------------------------------------- -dfsDom :: Node -> Dom s ()+dfsDom :: CNode -> Dom s () dfsDom i = do   _   <- go i   n0  <- zeroM@@ -293,10 +302,10 @@  initEnv :: Rooted -> ST s (Env s) initEnv (r0,g0) = do-  -- Graph renumbered to indices from 1 to |V|+  -- CGraph renumbered to indices from 1 to |V|   let (g,rnmap) = renum 1 g0       pred      = predG g -- reverse graph-      root      = rnmap IM.! r0 -- renamed root+      root      = rnmap WM.! r0 -- renamed root       n         = IM.size g       ns        = [0..n]       m         = n+1@@ -304,9 +313,9 @@   let bucket = IM.fromList         (zip ns (repeat mempty)) -  rna <- newI m+  rna <- newW m   writes rna (fmap swap-        (IM.toList rnmap))+        (WM.toList rnmap))    doms      <- newI m   sdno      <- newI m@@ -361,33 +370,33 @@  ----------------------------------------------------------------------------- -zeroM :: Dom s Node+zeroM :: Dom s CNode zeroM = gets zeroE-domM :: Node -> Dom s Node+domM :: CNode -> Dom s CNode domM = fetch domE-rootM :: Dom s Node+rootM :: Dom s CNode rootM = gets rootE-succsM :: Node -> Dom s [Node]+succsM :: CNode -> Dom s [CNode] succsM i = gets (IS.toList . (! i) . succE)-predsM :: Node -> Dom s [Node]+predsM :: CNode -> Dom s [CNode] predsM i = gets (IS.toList . (! i) . predE)-bucketM :: Node -> Dom s [Node]+bucketM :: CNode -> Dom s [CNode] bucketM i = gets (IS.toList . (! i) . bucketE)-sizeM :: Node -> Dom s Int+sizeM :: CNode -> Dom s Int sizeM = fetch sizeE-sdnoM :: Node -> Dom s Int+sdnoM :: CNode -> Dom s Int sdnoM = fetch sdnoE--- dfnM :: Node -> Dom s Int+-- dfnM :: CNode -> Dom s Int -- dfnM = fetch dfnE-ndfsM :: Int -> Dom s Node+ndfsM :: Int -> Dom s CNode ndfsM = fetch ndfsE-childM :: Node -> Dom s Node+childM :: CNode -> Dom s CNode childM = fetch childE-ancestorM :: Node -> Dom s Node+ancestorM :: CNode -> Dom s CNode ancestorM = fetch ancestorE-parentM :: Node -> Dom s Node+parentM :: CNode -> Dom s CNode parentM = fetch parentE-labelM :: Node -> Dom s Node+labelM :: CNode -> Dom s CNode labelM = fetch labelE nextM :: Dom s Int nextM = do@@ -422,6 +431,9 @@ newI :: Int -> ST s (Arr s Int) newI = new +newW :: Int -> ST s (Arr s Node)+newW = new+ writes :: (MArray (A s) a (ST s))      => Arr s a -> [(Int,a)] -> ST s () writes a xs = forM_ xs (\(i,x) -> (a.=x) i)@@ -431,18 +443,18 @@ (!) g n = maybe mempty id (IM.lookup n g)  fromAdj :: [(Node, [Node])] -> Graph-fromAdj = IM.fromList . fmap (second IS.fromList)+fromAdj = WM.fromList . fmap (second WS.fromList)  fromEdges :: [Edge] -> Graph-fromEdges = collectI IS.union fst (IS.singleton . snd)+fromEdges = collectW WS.union fst (WS.singleton . snd)  toAdj :: Graph -> [(Node, [Node])]-toAdj = fmap (second IS.toList) . IM.toList+toAdj = fmap (second WS.toList) . WM.toList  toEdges :: Graph -> [Edge] toEdges = concatMap (uncurry (fmap . (,))) . toAdj -predG :: Graph -> Graph+predG :: CGraph -> CGraph predG g = IM.unionWith IS.union (go g) g0   where g0 = fmap (const mempty) g         go = flip IM.foldrWithKey mempty (\i a m ->@@ -451,15 +463,24 @@                         m                        (IS.toList a)) +predGW :: Graph -> Graph+predGW g = WM.unionWith WS.union (go g) g0+  where g0 = fmap (const mempty) g+        go = flip WM.foldrWithKey mempty (\i a m ->+                foldl' (\m p -> WM.insertWith mappend p+                                      (WS.singleton i) m)+                        m+                       (WS.toList a))+ pruneReach :: Rooted -> Rooted pruneReach (r,g) = (r,g2)   where is = reachable               (maybe mempty id-                . flip IM.lookup g) $ r-        g2 = IM.fromList-            . fmap (second (IS.filter (`IS.member`is)))-            . filter ((`IS.member`is) . fst)-            . IM.toList $ g+                . flip WM.lookup g) $ r+        g2 = WM.fromList+            . fmap (second (WS.filter (`WS.member`is)))+            . filter ((`WS.member`is) . fst)+            . WM.toList $ g  tip :: Tree a -> (a, [Tree a]) tip (Node a ts) = (a, ts)@@ -476,26 +497,28 @@             in p acc' xs ++ concatMap (go acc') xs         p is = fmap (flip (,) is . rootLabel) -asGraph :: Tree Node -> Rooted-asGraph t@(Node a _) = let g = go t in (a, fromAdj g)+asCGraph :: Tree Node -> Rooted+asCGraph t@(Node a _) = let g = go t in (a, fromAdj g)   where go (Node a ts) = let as = (fst . unzip . fmap tip) ts                           in (a, as) : concatMap go ts  asTree :: Rooted -> Tree Node-asTree (r,g) = let go a = Node a (fmap go ((IS.toList . f) a))+asTree (r,g) = let go a = Node a (fmap go ((WS.toList . f) a))                    f = (g !)             in go r+  where (!) g n = maybe mempty id (WM.lookup n g) + reachable :: (Node -> NodeSet) -> (Node -> NodeSet)-reachable f a = go (IS.singleton a) a+reachable f a = go (WS.singleton a) a   where go seen a = let s = f a-                        as = IS.toList (s `IS.difference` seen)-                    in foldl' go (s `IS.union` seen) as+                        as = WS.toList (s `WS.difference` seen)+                    in foldl' go (s `WS.union` seen) as -collectI :: (c -> c -> c)-        -> (a -> Int) -> (a -> c) -> [a] -> IntMap c-collectI (<>) f g-  = foldl' (\m a -> IM.insertWith (<>)+collectW :: (c -> c -> c)+        -> (a -> Node) -> (a -> c) -> [a] -> Word64Map c+collectW (<>) f g+  = foldl' (\m a -> WM.insertWith (<>)                                   (f a)                                   (g a) m) mempty @@ -504,12 +527,12 @@ -- Gives nodes sequential names starting at n. -- Returns the new graph and a mapping. -- (renamed, old -> new)-renum :: Int -> Graph -> (Graph, NodeMap Node)+renum :: Int -> Graph -> (CGraph, NodeMap CNode) renum from = (\(_,m,g)->(g,m))-  . IM.foldrWithKey+  . WM.foldrWithKey       (\i ss (!n,!env,!new)->           let (j,n2,env2) = go n env i-              (n3,env3,ss2) = IS.fold+              (n3,env3,ss2) = WS.fold                 (\k (!n,!env,!new)->                     case go n env k of                       (l,n2,env2)-> (n2,env2,l `IS.insert` new))@@ -517,13 +540,13 @@               new2 = IM.insertWith IS.union j ss2 new           in (n3,env3,new2)) (from,mempty,mempty)   where go :: Int-           -> NodeMap Node+           -> NodeMap CNode            -> Node-           -> (Node,Int,NodeMap Node)+           -> (CNode,Int,NodeMap CNode)         go !n !env i =-          case IM.lookup i env of+          case WM.lookup i env of             Just j -> (j,n,env)-            Nothing -> (n,n+1,IM.insert i n env)+            Nothing -> (n,n+1,WM.insert i n env)  ----------------------------------------------------------------------------- 
GHC/CmmToAsm/Wasm/Asm.hs view
@@ -14,7 +14,7 @@ import Data.ByteString.Builder import Data.Coerce import Data.Foldable-import qualified Data.IntSet as IS+import qualified GHC.Data.Word64Set as WS import Data.Maybe import Data.Semigroup import GHC.Cmm@@ -181,9 +181,9 @@ asmTellSectionHeader k = asmTellTabLine $ ".section " <> k <> ",\"\",@"  asmTellDataSection ::-  WasmTypeTag w -> IS.IntSet -> SymName -> DataSection -> WasmAsmM ()+  WasmTypeTag w -> WS.Word64Set -> SymName -> DataSection -> WasmAsmM () asmTellDataSection ty_word def_syms sym DataSection {..} = do-  when (getKey (getUnique sym) `IS.member` def_syms) $ asmTellDefSym sym+  when (getKey (getUnique sym) `WS.member` def_syms) $ asmTellDefSym sym   asmTellSectionHeader sec_name   asmTellAlign dataSectionAlignment   asmTellTabLine asm_size@@ -420,12 +420,12 @@  asmTellFunc ::   WasmTypeTag w ->-  IS.IntSet ->+  WS.Word64Set ->   SymName ->   (([SomeWasmType], [SomeWasmType]), FuncBody w) ->   WasmAsmM () asmTellFunc ty_word def_syms sym (func_ty, FuncBody {..}) = do-  when (getKey (getUnique sym) `IS.member` def_syms) $ asmTellDefSym sym+  when (getKey (getUnique sym) `WS.member` def_syms) $ asmTellDefSym sym   asmTellSectionHeader $ ".text." <> asm_sym   asmTellLine $ asm_sym <> ":"   asmTellFuncType sym func_ty
GHC/CmmToAsm/Wasm/FromCmm.hs view
@@ -26,7 +26,7 @@ import qualified Data.ByteString as BS import Data.Foldable import Data.Functor-import qualified Data.IntSet as IS+import qualified GHC.Data.Word64Set as WS import Data.Semigroup import Data.String import Data.Traversable@@ -1553,7 +1553,7 @@   SymDefault -> wasmModifyM $ \s ->     s       { defaultSyms =-          IS.insert+          WS.insert             (getKey $ getUnique sym)             $ defaultSyms s       }
GHC/CmmToAsm/Wasm/Types.hs view
@@ -52,7 +52,7 @@ import Data.ByteString (ByteString) import Data.Coerce import Data.Functor-import qualified Data.IntSet as IS+import qualified GHC.Data.Word64Set as WS import Data.Kind import Data.String import Data.Type.Equality@@ -197,7 +197,7 @@ type SymMap = UniqMap SymName  -- | No need to remember the symbols.-type SymSet = IS.IntSet+type SymSet = WS.Word64Set  type GlobalInfo = (SymName, SomeWasmType) @@ -427,7 +427,7 @@   WasmCodeGenState     { wasmPlatform =         platform,-      defaultSyms = IS.empty,+      defaultSyms = WS.empty,       funcTypes = emptyUniqMap,       funcBodies =         emptyUniqMap,
GHC/CmmToLlvm/Base.hs view
@@ -260,7 +260,7 @@   , envConfig    :: !LlvmCgConfig    -- ^ Configuration for LLVM code gen   , envLogger    :: !Logger          -- ^ Logger   , envOutput    :: BufHandle        -- ^ Output buffer-  , envMask      :: !Char            -- ^ Mask for creating unique values+  , envTag       :: !Char            -- ^ Tag for creating unique values   , envFreshMeta :: MetaId           -- ^ Supply of fresh metadata IDs   , envUniqMeta  :: UniqFM Unique MetaId   -- ^ Global metadata nodes   , envFunMap    :: LlvmEnvMap       -- ^ Global functions so far, with type@@ -292,12 +292,12 @@  instance MonadUnique LlvmM where     getUniqueSupplyM = do-        mask <- getEnv envMask-        liftIO $! mkSplitUniqSupply mask+        tag <- getEnv envTag+        liftIO $! mkSplitUniqSupply tag      getUniqueM = do-        mask <- getEnv envMask-        liftIO $! uniqFromMask mask+        tag <- getEnv envTag+        liftIO $! uniqFromTag tag  -- | Lifting of IO actions. Not exported, as we want to encapsulate IO. liftIO :: IO a -> LlvmM a@@ -318,7 +318,7 @@                       , envConfig    = cfg                       , envLogger    = logger                       , envOutput    = out-                      , envMask      = 'n'+                      , envTag       = 'n'                       , envFreshMeta = MetaId 0                       , envUniqMeta  = emptyUFM                       }
GHC/Core/Opt/Monad.hs view
@@ -20,7 +20,7 @@     initRuleEnv, getExternalRuleBase,     getDynFlags, getPackageFamInstEnv,     getInteractiveContext,-    getUniqMask,+    getUniqTag,     getNamePprCtx, getSrcSpanM,      -- ** Writing to the monad@@ -117,7 +117,7 @@         cr_name_ppr_ctx        :: NamePprCtx,         cr_loc                 :: SrcSpan,   -- Use this for log/error messages so they                                              -- are at least tagged with the right source file-        cr_uniq_mask           :: !Char      -- Mask for creating unique values+        cr_uniq_tag            :: !Char      -- Tag for creating unique values }  -- Note: CoreWriter used to be defined with data, rather than newtype.  If it@@ -167,12 +167,12 @@  instance MonadUnique CoreM where     getUniqueSupplyM = do-        mask <- read cr_uniq_mask-        liftIO $! mkSplitUniqSupply mask+        tag <- read cr_uniq_tag+        liftIO $! mkSplitUniqSupply tag      getUniqueM = do-        mask <- read cr_uniq_mask-        liftIO $! uniqFromMask mask+        tag <- read cr_uniq_tag+        liftIO $! uniqFromTag tag  runCoreM :: HscEnv          -> RuleBase@@ -182,7 +182,7 @@          -> SrcSpan          -> CoreM a          -> IO (a, SimplCount)-runCoreM hsc_env rule_base mask mod name_ppr_ctx loc m+runCoreM hsc_env rule_base tag mod name_ppr_ctx loc m   = liftM extract $ runIOEnv reader $ unCoreM m   where     reader = CoreReader {@@ -191,7 +191,7 @@             cr_module = mod,             cr_name_ppr_ctx = name_ppr_ctx,             cr_loc = loc,-            cr_uniq_mask = mask+            cr_uniq_tag = tag         }      extract :: (a, CoreWriter) -> (a, SimplCount)@@ -261,8 +261,8 @@ addSimplCount :: SimplCount -> CoreM () addSimplCount count = write (CoreWriter { cw_simpl_count = count }) -getUniqMask :: CoreM Char-getUniqMask = read cr_uniq_mask+getUniqTag :: CoreM Char+getUniqTag = read cr_uniq_tag  -- Convenience accessors for useful fields of HscEnv 
GHC/Core/Opt/Pipeline.hs view
@@ -77,9 +77,9 @@                                 , mg_loc     = loc                                 , mg_rdr_env = rdr_env })   = do { let builtin_passes = getCoreToDo dflags hpt_rule_base extra_vars-             uniq_mask = 's'+             uniq_tag = 's' -       ; (guts2, stats) <- runCoreM hsc_env hpt_rule_base uniq_mask mod+       ; (guts2, stats) <- runCoreM hsc_env hpt_rule_base uniq_tag mod                                     name_ppr_ctx loc $                            do { hsc_env' <- getHscEnv                               ; all_passes <- withPlugins (hsc_plugins hsc_env')
GHC/Core/Opt/Simplify/Monad.hs view
@@ -180,13 +180,13 @@ ************************************************************************ -} --- See Note [Uniques for wired-in prelude things and known masks] in GHC.Builtin.Uniques-simplMask :: Char-simplMask = 's'+-- See Note [Uniques for wired-in prelude things and known tags] in GHC.Builtin.Uniques+simplTag :: Char+simplTag = 's'  instance MonadUnique SimplM where-    getUniqueSupplyM = liftIO $ mkSplitUniqSupply simplMask-    getUniqueM = liftIO $ uniqFromMask simplMask+    getUniqueSupplyM = liftIO $ mkSplitUniqSupply simplTag+    getUniqueM = liftIO $ uniqFromTag simplTag  instance HasLogger SimplM where     getLogger = gets st_logger
GHC/Data/Graph/UnVar.hs view
@@ -35,8 +35,9 @@ import GHC.Types.Var import GHC.Utils.Outputable import GHC.Types.Unique+import GHC.Word -import qualified Data.IntSet as S+import qualified GHC.Data.Word64Set as S  -- We need a type for sets of variables (UnVarSet). -- We do not use VarSet, because for that we need to have the actual variable@@ -44,10 +45,10 @@ -- Therefore, use a IntSet directly (which is likely also a bit more efficient).  -- Set of uniques, i.e. for adjacent nodes-newtype UnVarSet = UnVarSet (S.IntSet)+newtype UnVarSet = UnVarSet S.Word64Set     deriving Eq -k :: Var -> Int+k :: Var -> Word64 k v = getKey (getUnique v)  domUFMUnVarSet :: UniqFM key elt -> UnVarSet@@ -92,7 +93,7 @@  instance Outputable UnVarSet where     ppr (UnVarSet s) = braces $-        hcat $ punctuate comma [ ppr (getUnique i) | i <- S.toList s]+        hcat $ punctuate comma [ ppr (mkUniqueGrimily i) | i <- S.toList s]  data UnVarGraph = CBPG  !UnVarSet !UnVarSet -- ^ complete bipartite graph                 | CG    !UnVarSet           -- ^ complete graph
+ GHC/Data/Word64Map.hs view
@@ -0,0 +1,62 @@+{-# LANGUAGE CPP #-}+#if !defined(TESTING) && defined(__GLASGOW_HASKELL__)+{-# LANGUAGE Safe #-}+#endif+#ifdef __GLASGOW_HASKELL__+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MonoLocalBinds #-}+#endif++#include "containers.h"++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Word64Map+-- Copyright   :  (c) Daan Leijen 2002+--                (c) Andriy Palamarchuk 2008+-- License     :  BSD-style+-- Maintainer  :  libraries@haskell.org+-- Portability :  portable+--+-- An efficient implementation of maps from integer keys to values+-- (dictionaries).+--+-- This module re-exports the value lazy "Data.Word64Map.Lazy" API, plus+-- several deprecated value strict functions. Please note that these functions+-- have different strictness properties than those in "Data.Word64Map.Strict":+-- they only evaluate the result of the combining function. For example, the+-- default value to 'insertWith'' is only evaluated if the combining function+-- is called and uses it.+--+-- These modules are intended to be imported qualified, to avoid name+-- clashes with Prelude functions, e.g.+--+-- >  import Data.Word64Map (Word64Map)+-- >  import qualified Data.Word64Map as Word64Map+--+-- The implementation is based on /big-endian patricia trees/.  This data+-- structure performs especially well on binary operations like 'union'+-- and 'intersection'.  However, my benchmarks show that it is also+-- (much) faster on insertions and deletions when compared to a generic+-- size-balanced map implementation (see "Data.Map").+--+--    * Chris Okasaki and Andy Gill,  \"/Fast Mergeable Integer Maps/\",+--      Workshop on ML, September 1998, pages 77-86,+--      <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.37.5452>+--+--    * D.R. Morrison, \"/PATRICIA -- Practical Algorithm To Retrieve Information Coded In Alphanumeric/\",+--      Journal of the ACM, 15(4), October 1968, pages 514-534.+--+-- Operation comments contain the operation time complexity in+-- the Big-O notation <http://en.wikipedia.org/wiki/Big_O_notation>.+-- Many operations have a worst-case complexity of \(O(\min(n,64))\).+-- This means that the operation can become linear in the number of+-- elements with a maximum of \(64\)+-----------------------------------------------------------------------------++module GHC.Data.Word64Map+    ( module GHC.Data.Word64Map.Lazy+    ) where++import GHC.Data.Word64Map.Lazy
+ GHC/Data/Word64Map/Internal.hs view
@@ -0,0 +1,3607 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE PatternGuards #-}+#ifdef __GLASGOW_HASKELL__+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeFamilies #-}+#endif+#if !defined(TESTING) && defined(__GLASGOW_HASKELL__)+{-# LANGUAGE Trustworthy #-}+#endif++{-# OPTIONS_HADDOCK not-home #-}+{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}++#include "containers.h"++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Word64Map.Internal+-- Copyright   :  (c) Daan Leijen 2002+--                (c) Andriy Palamarchuk 2008+--                (c) wren romano 2016+-- License     :  BSD-style+-- Maintainer  :  libraries@haskell.org+-- Portability :  portable+--+-- = WARNING+--+-- This module is considered __internal__.+--+-- The Package Versioning Policy __does not apply__.+--+-- The contents of this module may change __in any way whatsoever__+-- and __without any warning__ between minor versions of this package.+--+-- Authors importing this module are expected to track development+-- closely.+--+-- = Description+--+-- This defines the data structures and core (hidden) manipulations+-- on representations.+--+-- @since 0.5.9+-----------------------------------------------------------------------------++-- [Note: INLINE bit fiddling]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- It is essential that the bit fiddling functions like mask, zero, branchMask+-- etc are inlined. If they do not, the memory allocation skyrockets. The GHC+-- usually gets it right, but it is disastrous if it does not. Therefore we+-- explicitly mark these functions INLINE.+++-- [Note: Local 'go' functions and capturing]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- Care must be taken when using 'go' function which captures an argument.+-- Sometimes (for example when the argument is passed to a data constructor,+-- as in insert), GHC heap-allocates more than necessary. Therefore C-- code+-- must be checked for increased allocation when creating and modifying such+-- functions.+++-- [Note: Order of constructors]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- The order of constructors of Word64Map matters when considering performance.+-- Currently in GHC 7.0, when type has 3 constructors, they are matched from+-- the first to the last -- the best performance is achieved when the+-- constructors are ordered by frequency.+-- On GHC 7.0, reordering constructors from Nil | Tip | Bin to Bin | Tip | Nil+-- improves the benchmark by circa 10%.+--++module GHC.Data.Word64Map.Internal (+    -- * Map type+      Word64Map(..), Key          -- instance Eq,Show++    -- * Operators+    , (!), (!?), (\\)++    -- * Query+    , null+    , size+    , member+    , notMember+    , lookup+    , findWithDefault+    , lookupLT+    , lookupGT+    , lookupLE+    , lookupGE+    , disjoint++    -- * Construction+    , empty+    , singleton++    -- ** Insertion+    , insert+    , insertWith+    , insertWithKey+    , insertLookupWithKey++    -- ** Delete\/Update+    , delete+    , adjust+    , adjustWithKey+    , update+    , updateWithKey+    , updateLookupWithKey+    , alter+    , alterF++    -- * Combine++    -- ** Union+    , union+    , unionWith+    , unionWithKey+    , unions+    , unionsWith++    -- ** Difference+    , difference+    , differenceWith+    , differenceWithKey++    -- ** Intersection+    , intersection+    , intersectionWith+    , intersectionWithKey++    -- ** Compose+    , compose++    -- ** General combining function+    , SimpleWhenMissing+    , SimpleWhenMatched+    , runWhenMatched+    , runWhenMissing+    , merge+    -- *** @WhenMatched@ tactics+    , zipWithMaybeMatched+    , zipWithMatched+    -- *** @WhenMissing@ tactics+    , mapMaybeMissing+    , dropMissing+    , preserveMissing+    , mapMissing+    , filterMissing++    -- ** Applicative general combining function+    , WhenMissing (..)+    , WhenMatched (..)+    , mergeA+    -- *** @WhenMatched@ tactics+    -- | The tactics described for 'merge' work for+    -- 'mergeA' as well. Furthermore, the following+    -- are available.+    , zipWithMaybeAMatched+    , zipWithAMatched+    -- *** @WhenMissing@ tactics+    -- | The tactics described for 'merge' work for+    -- 'mergeA' as well. Furthermore, the following+    -- are available.+    , traverseMaybeMissing+    , traverseMissing+    , filterAMissing++    -- ** Deprecated general combining function+    , mergeWithKey+    , mergeWithKey'++    -- * Traversal+    -- ** Map+    , map+    , mapWithKey+    , traverseWithKey+    , traverseMaybeWithKey+    , mapAccum+    , mapAccumWithKey+    , mapAccumRWithKey+    , mapKeys+    , mapKeysWith+    , mapKeysMonotonic++    -- * Folds+    , foldr+    , foldl+    , foldrWithKey+    , foldlWithKey+    , foldMapWithKey++    -- ** Strict folds+    , foldr'+    , foldl'+    , foldrWithKey'+    , foldlWithKey'++    -- * Conversion+    , elems+    , keys+    , assocs+    , keysSet+    , fromSet++    -- ** Lists+    , toList+    , fromList+    , fromListWith+    , fromListWithKey++    -- ** Ordered lists+    , toAscList+    , toDescList+    , fromAscList+    , fromAscListWith+    , fromAscListWithKey+    , fromDistinctAscList++    -- * Filter+    , filter+    , filterWithKey+    , restrictKeys+    , withoutKeys+    , partition+    , partitionWithKey++    , takeWhileAntitone+    , dropWhileAntitone+    , spanAntitone++    , mapMaybe+    , mapMaybeWithKey+    , mapEither+    , mapEitherWithKey++    , split+    , splitLookup+    , splitRoot++    -- * Submap+    , isSubmapOf, isSubmapOfBy+    , isProperSubmapOf, isProperSubmapOfBy++    -- * Min\/Max+    , lookupMin+    , lookupMax+    , findMin+    , findMax+    , deleteMin+    , deleteMax+    , deleteFindMin+    , deleteFindMax+    , updateMin+    , updateMax+    , updateMinWithKey+    , updateMaxWithKey+    , minView+    , maxView+    , minViewWithKey+    , maxViewWithKey++    -- * Debugging+    , showTree+    , showTreeWith++    -- * Internal types+    , Mask, Prefix, Nat++    -- * Utility+    , natFromInt+    , intFromNat+    , link+    , linkWithMask+    , bin+    , binCheckLeft+    , binCheckRight+    , zero+    , nomatch+    , match+    , mask+    , maskW+    , shorter+    , branchMask+    , highestBitMask++    -- * Used by "Word64Map.Merge.Lazy" and "Word64Map.Merge.Strict"+    , mapWhenMissing+    , mapWhenMatched+    , lmapWhenMissing+    , contramapFirstWhenMatched+    , contramapSecondWhenMatched+    , mapGentlyWhenMissing+    , mapGentlyWhenMatched+    ) where++import GHC.Prelude.Basic hiding+  (lookup, filter, foldr, foldl, foldl', null, map)++import Data.Functor.Identity (Identity (..))+import Data.Semigroup (Semigroup(stimes,(<>)),stimesIdempotentMonoid)+import Data.Functor.Classes++import Control.DeepSeq (NFData(rnf))+import qualified Data.Foldable as Foldable+import Data.Maybe (fromMaybe)++import GHC.Data.Word64Set.Internal (Key)+import qualified GHC.Data.Word64Set.Internal as Word64Set+import GHC.Utils.Containers.Internal.BitUtil+import GHC.Utils.Containers.Internal.StrictPair++#ifdef __GLASGOW_HASKELL__+import Data.Coerce+import Data.Data (Data(..), Constr, mkConstr, constrIndex, Fixity(Prefix),+                  DataType, mkDataType, gcast1)+import GHC.Exts (build)+import qualified GHC.Exts as GHCExts+import Text.Read+#endif+import qualified Control.Category as Category+import Data.Word+++-- A "Nat" is a 64 bit machine word (an unsigned Int64)+type Nat = Word64++natFromInt :: Key -> Nat+natFromInt = id+{-# INLINE natFromInt #-}++intFromNat :: Nat -> Key+intFromNat = id+{-# INLINE intFromNat #-}++{--------------------------------------------------------------------+  Types+--------------------------------------------------------------------}+++-- | A map of integers to values @a@.++-- See Note: Order of constructors+data Word64Map a = Bin {-# UNPACK #-} !Prefix+                    {-# UNPACK #-} !Mask+                    !(Word64Map a)+                    !(Word64Map a)+-- Fields:+--   prefix: The most significant bits shared by all keys in this Bin.+--   mask: The switching bit to determine if a key should follow the left+--         or right subtree of a 'Bin'.+-- Invariant: Nil is never found as a child of Bin.+-- Invariant: The Mask is a power of 2. It is the largest bit position at which+--            two keys of the map differ.+-- Invariant: Prefix is the common high-order bits that all elements share to+--            the left of the Mask bit.+-- Invariant: In (Bin prefix mask left right), left consists of the elements that+--            don't have the mask bit set; right is all the elements that do.+              | Tip {-# UNPACK #-} !Key a+              | Nil++type Prefix = Word64+type Mask   = Word64+++-- Some stuff from "Data.Word64Set.Internal", for 'restrictKeys' and+-- 'withoutKeys' to use.+type Word64SetPrefix = Word64+type Word64SetBitMap = Word64++bitmapOf :: Word64 -> Word64SetBitMap+bitmapOf x = shiftLL 1 (fromIntegral (x .&. Word64Set.suffixBitMask))+{-# INLINE bitmapOf #-}++{--------------------------------------------------------------------+  Operators+--------------------------------------------------------------------}++-- | \(O(\min(n,W))\). Find the value at a key.+-- Calls 'error' when the element can not be found.+--+-- > fromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map+-- > fromList [(5,'a'), (3,'b')] ! 5 == 'a'++(!) :: Word64Map a -> Key -> a+(!) m k = find k m++-- | \(O(\min(n,W))\). Find the value at a key.+-- Returns 'Nothing' when the element can not be found.+--+-- > fromList [(5,'a'), (3,'b')] !? 1 == Nothing+-- > fromList [(5,'a'), (3,'b')] !? 5 == Just 'a'+--+-- @since 0.5.11++(!?) :: Word64Map a -> Key -> Maybe a+(!?) m k = lookup k m++-- | Same as 'difference'.+(\\) :: Word64Map a -> Word64Map b -> Word64Map a+m1 \\ m2 = difference m1 m2++infixl 9 !?,\\{-This comment teaches CPP correct behaviour -}++{--------------------------------------------------------------------+  Types+--------------------------------------------------------------------}++instance Monoid (Word64Map a) where+    mempty  = empty+    mconcat = unions+    mappend = (<>)++-- | @since 0.5.7+instance Semigroup (Word64Map a) where+    (<>)    = union+    stimes  = stimesIdempotentMonoid++-- | Folds in order of increasing key.+instance Foldable.Foldable Word64Map where+  fold = go+    where go Nil = mempty+          go (Tip _ v) = v+          go (Bin _ m l r)+            | m < 0     = go r `mappend` go l+            | otherwise = go l `mappend` go r+  {-# INLINABLE fold #-}+  foldr = foldr+  {-# INLINE foldr #-}+  foldl = foldl+  {-# INLINE foldl #-}+  foldMap f t = go t+    where go Nil = mempty+          go (Tip _ v) = f v+          go (Bin _ m l r)+            | m < 0     = go r `mappend` go l+            | otherwise = go l `mappend` go r+  {-# INLINE foldMap #-}+  foldl' = foldl'+  {-# INLINE foldl' #-}+  foldr' = foldr'+  {-# INLINE foldr' #-}+  length = size+  {-# INLINE length #-}+  null   = null+  {-# INLINE null #-}+  toList = elems -- NB: Foldable.toList /= Word64Map.toList+  {-# INLINE toList #-}+  elem = go+    where go !_ Nil = False+          go x (Tip _ y) = x == y+          go x (Bin _ _ l r) = go x l || go x r+  {-# INLINABLE elem #-}+  maximum = start+    where start Nil = error "Data.Foldable.maximum (for Data.Word64Map): empty map"+          start (Tip _ y) = y+          start (Bin _ m l r)+            | m < 0     = go (start r) l+            | otherwise = go (start l) r++          go !m Nil = m+          go m (Tip _ y) = max m y+          go m (Bin _ _ l r) = go (go m l) r+  {-# INLINABLE maximum #-}+  minimum = start+    where start Nil = error "Data.Foldable.minimum (for Data.Word64Map): empty map"+          start (Tip _ y) = y+          start (Bin _ m l r)+            | m < 0     = go (start r) l+            | otherwise = go (start l) r++          go !m Nil = m+          go m (Tip _ y) = min m y+          go m (Bin _ _ l r) = go (go m l) r+  {-# INLINABLE minimum #-}+  sum = foldl' (+) 0+  {-# INLINABLE sum #-}+  product = foldl' (*) 1+  {-# INLINABLE product #-}++-- | Traverses in order of increasing key.+instance Traversable Word64Map where+    traverse f = traverseWithKey (\_ -> f)+    {-# INLINE traverse #-}++instance NFData a => NFData (Word64Map a) where+    rnf Nil = ()+    rnf (Tip _ v) = rnf v+    rnf (Bin _ _ l r) = rnf l `seq` rnf r++#if __GLASGOW_HASKELL__++{--------------------------------------------------------------------+  A Data instance+--------------------------------------------------------------------}++-- This instance preserves data abstraction at the cost of inefficiency.+-- We provide limited reflection services for the sake of data abstraction.++instance Data a => Data (Word64Map a) where+  gfoldl f z im = z fromList `f` (toList im)+  toConstr _     = fromListConstr+  gunfold k z c  = case constrIndex c of+    1 -> k (z fromList)+    _ -> error "gunfold"+  dataTypeOf _   = intMapDataType+  dataCast1 f    = gcast1 f++fromListConstr :: Constr+fromListConstr = mkConstr intMapDataType "fromList" [] Prefix++intMapDataType :: DataType+intMapDataType = mkDataType "Data.Word64Map.Internal.Word64Map" [fromListConstr]++#endif++{--------------------------------------------------------------------+  Query+--------------------------------------------------------------------}+-- | \(O(1)\). Is the map empty?+--+-- > Data.Word64Map.null (empty)           == True+-- > Data.Word64Map.null (singleton 1 'a') == False++null :: Word64Map a -> Bool+null Nil = True+null _   = False+{-# INLINE null #-}++-- | \(O(n)\). Number of elements in the map.+--+-- > size empty                                   == 0+-- > size (singleton 1 'a')                       == 1+-- > size (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3+size :: Word64Map a -> Int+size = go 0+  where+    go !acc (Bin _ _ l r) = go (go acc l) r+    go acc (Tip _ _) = 1 + acc+    go acc Nil = acc++-- | \(O(\min(n,W))\). Is the key a member of the map?+--+-- > member 5 (fromList [(5,'a'), (3,'b')]) == True+-- > member 1 (fromList [(5,'a'), (3,'b')]) == False++-- See Note: Local 'go' functions and capturing]+member :: Key -> Word64Map a -> Bool+member !k = go+  where+    go (Bin p m l r) | nomatch k p m = False+                     | zero k m  = go l+                     | otherwise = go r+    go (Tip kx _) = k == kx+    go Nil = False++-- | \(O(\min(n,W))\). Is the key not a member of the map?+--+-- > notMember 5 (fromList [(5,'a'), (3,'b')]) == False+-- > notMember 1 (fromList [(5,'a'), (3,'b')]) == True++notMember :: Key -> Word64Map a -> Bool+notMember k m = not $ member k m++-- | \(O(\min(n,W))\). Lookup the value at a key in the map. See also 'Data.Map.lookup'.++-- See Note: Local 'go' functions and capturing+lookup :: Key -> Word64Map a -> Maybe a+lookup !k = go+  where+    go (Bin _p m l r) | zero k m  = go l+                      | otherwise = go r+    go (Tip kx x) | k == kx   = Just x+                  | otherwise = Nothing+    go Nil = Nothing++-- See Note: Local 'go' functions and capturing]+find :: Key -> Word64Map a -> a+find !k = go+  where+    go (Bin _p m l r) | zero k m  = go l+                      | otherwise = go r+    go (Tip kx x) | k == kx   = x+                  | otherwise = not_found+    go Nil = not_found++    not_found = error ("Word64Map.!: key " ++ show k ++ " is not an element of the map")++-- | \(O(\min(n,W))\). The expression @('findWithDefault' def k map)@+-- returns the value at key @k@ or returns @def@ when the key is not an+-- element of the map.+--+-- > findWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'+-- > findWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'++-- See Note: Local 'go' functions and capturing]+findWithDefault :: a -> Key -> Word64Map a -> a+findWithDefault def !k = go+  where+    go (Bin p m l r) | nomatch k p m = def+                     | zero k m  = go l+                     | otherwise = go r+    go (Tip kx x) | k == kx   = x+                  | otherwise = def+    go Nil = def++-- | \(O(\min(n,W))\). Find largest key smaller than the given one and return the+-- corresponding (key, value) pair.+--+-- > lookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing+-- > lookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')++-- See Note: Local 'go' functions and capturing.+lookupLT :: Key -> Word64Map a -> Maybe (Key, a)+lookupLT !k t = case t of+    Bin _ m l r | m < 0 -> if k >= 0 then go r l else go Nil r+    _ -> go Nil t+  where+    go def (Bin p m l r)+      | nomatch k p m = if k < p then unsafeFindMax def else unsafeFindMax r+      | zero k m  = go def l+      | otherwise = go l r+    go def (Tip ky y)+      | k <= ky   = unsafeFindMax def+      | otherwise = Just (ky, y)+    go def Nil = unsafeFindMax def++-- | \(O(\min(n,W))\). Find smallest key greater than the given one and return the+-- corresponding (key, value) pair.+--+-- > lookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')+-- > lookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing++-- See Note: Local 'go' functions and capturing.+lookupGT :: Key -> Word64Map a -> Maybe (Key, a)+lookupGT !k t = case t of+    Bin _ m l r | m < 0 -> if k >= 0 then go Nil l else go l r+    _ -> go Nil t+  where+    go def (Bin p m l r)+      | nomatch k p m = if k < p then unsafeFindMin l else unsafeFindMin def+      | zero k m  = go r l+      | otherwise = go def r+    go def (Tip ky y)+      | k >= ky   = unsafeFindMin def+      | otherwise = Just (ky, y)+    go def Nil = unsafeFindMin def++-- | \(O(\min(n,W))\). Find largest key smaller or equal to the given one and return+-- the corresponding (key, value) pair.+--+-- > lookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing+-- > lookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')+-- > lookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')++-- See Note: Local 'go' functions and capturing.+lookupLE :: Key -> Word64Map a -> Maybe (Key, a)+lookupLE !k t = case t of+    Bin _ m l r | m < 0 -> if k >= 0 then go r l else go Nil r+    _ -> go Nil t+  where+    go def (Bin p m l r)+      | nomatch k p m = if k < p then unsafeFindMax def else unsafeFindMax r+      | zero k m  = go def l+      | otherwise = go l r+    go def (Tip ky y)+      | k < ky    = unsafeFindMax def+      | otherwise = Just (ky, y)+    go def Nil = unsafeFindMax def++-- | \(O(\min(n,W))\). Find smallest key greater or equal to the given one and return+-- the corresponding (key, value) pair.+--+-- > lookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')+-- > lookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')+-- > lookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing++-- See Note: Local 'go' functions and capturing.+lookupGE :: Key -> Word64Map a -> Maybe (Key, a)+lookupGE !k t = case t of+    Bin _ m l r | m < 0 -> if k >= 0 then go Nil l else go l r+    _ -> go Nil t+  where+    go def (Bin p m l r)+      | nomatch k p m = if k < p then unsafeFindMin l else unsafeFindMin def+      | zero k m  = go r l+      | otherwise = go def r+    go def (Tip ky y)+      | k > ky    = unsafeFindMin def+      | otherwise = Just (ky, y)+    go def Nil = unsafeFindMin def+++-- Helper function for lookupGE and lookupGT. It assumes that if a Bin node is+-- given, it has m > 0.+unsafeFindMin :: Word64Map a -> Maybe (Key, a)+unsafeFindMin Nil = Nothing+unsafeFindMin (Tip ky y) = Just (ky, y)+unsafeFindMin (Bin _ _ l _) = unsafeFindMin l++-- Helper function for lookupLE and lookupLT. It assumes that if a Bin node is+-- given, it has m > 0.+unsafeFindMax :: Word64Map a -> Maybe (Key, a)+unsafeFindMax Nil = Nothing+unsafeFindMax (Tip ky y) = Just (ky, y)+unsafeFindMax (Bin _ _ _ r) = unsafeFindMax r++{--------------------------------------------------------------------+  Disjoint+--------------------------------------------------------------------}+-- | \(O(n+m)\). Check whether the key sets of two maps are disjoint+-- (i.e. their 'intersection' is empty).+--+-- > disjoint (fromList [(2,'a')]) (fromList [(1,()), (3,())])   == True+-- > disjoint (fromList [(2,'a')]) (fromList [(1,'a'), (2,'b')]) == False+-- > disjoint (fromList [])        (fromList [])                 == True+--+-- > disjoint a b == null (intersection a b)+--+-- @since 0.6.2.1+disjoint :: Word64Map a -> Word64Map b -> Bool+disjoint Nil _ = True+disjoint _ Nil = True+disjoint (Tip kx _) ys = notMember kx ys+disjoint xs (Tip ky _) = notMember ky xs+disjoint t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)+  | shorter m1 m2 = disjoint1+  | shorter m2 m1 = disjoint2+  | p1 == p2      = disjoint l1 l2 && disjoint r1 r2+  | otherwise     = True+  where+    disjoint1 | nomatch p2 p1 m1 = True+              | zero p2 m1       = disjoint l1 t2+              | otherwise        = disjoint r1 t2+    disjoint2 | nomatch p1 p2 m2 = True+              | zero p1 m2       = disjoint t1 l2+              | otherwise        = disjoint t1 r2++{--------------------------------------------------------------------+  Compose+--------------------------------------------------------------------}+-- | Relate the keys of one map to the values of+-- the other, by using the values of the former as keys for lookups+-- in the latter.+--+-- Complexity: \( O(n * \min(m,W)) \), where \(m\) is the size of the first argument+--+-- > compose (fromList [('a', "A"), ('b', "B")]) (fromList [(1,'a'),(2,'b'),(3,'z')]) = fromList [(1,"A"),(2,"B")]+--+-- @+-- ('compose' bc ab '!?') = (bc '!?') <=< (ab '!?')+-- @+--+-- __Note:__ Prior to v0.6.4, "Data.Word64Map.Strict" exposed a version of+-- 'compose' that forced the values of the output 'Word64Map'. This version does+-- not force these values.+--+-- @since 0.6.3.1+compose :: Word64Map c -> Word64Map Word64 -> Word64Map c+compose bc !ab+  | null bc = empty+  | otherwise = mapMaybe (bc !?) ab++{--------------------------------------------------------------------+  Construction+--------------------------------------------------------------------}+-- | \(O(1)\). The empty map.+--+-- > empty      == fromList []+-- > size empty == 0++empty :: Word64Map a+empty+  = Nil+{-# INLINE empty #-}++-- | \(O(1)\). A map of one element.+--+-- > singleton 1 'a'        == fromList [(1, 'a')]+-- > size (singleton 1 'a') == 1++singleton :: Key -> a -> Word64Map a+singleton k x+  = Tip k x+{-# INLINE singleton #-}++{--------------------------------------------------------------------+  Insert+--------------------------------------------------------------------}+-- | \(O(\min(n,W))\). Insert a new key\/value pair in the map.+-- If the key is already present in the map, the associated value is+-- replaced with the supplied value, i.e. 'insert' is equivalent to+-- @'insertWith' 'const'@.+--+-- > insert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]+-- > insert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]+-- > insert 5 'x' empty                         == singleton 5 'x'++insert :: Key -> a -> Word64Map a -> Word64Map a+insert !k x t@(Bin p m l r)+  | nomatch k p m = link k (Tip k x) p t+  | zero k m      = Bin p m (insert k x l) r+  | otherwise     = Bin p m l (insert k x r)+insert k x t@(Tip ky _)+  | k==ky         = Tip k x+  | otherwise     = link k (Tip k x) ky t+insert k x Nil = Tip k x++-- right-biased insertion, used by 'union'+-- | \(O(\min(n,W))\). Insert with a combining function.+-- @'insertWith' f key value mp@+-- will insert the pair (key, value) into @mp@ if key does+-- not exist in the map. If the key does exist, the function will+-- insert @f new_value old_value@.+--+-- > insertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]+-- > insertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]+-- > insertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"++insertWith :: (a -> a -> a) -> Key -> a -> Word64Map a -> Word64Map a+insertWith f k x t+  = insertWithKey (\_ x' y' -> f x' y') k x t++-- | \(O(\min(n,W))\). Insert with a combining function.+-- @'insertWithKey' f key value mp@+-- will insert the pair (key, value) into @mp@ if key does+-- not exist in the map. If the key does exist, the function will+-- insert @f key new_value old_value@.+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > insertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]+-- > insertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]+-- > insertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"++insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> Word64Map a -> Word64Map a+insertWithKey f !k x t@(Bin p m l r)+  | nomatch k p m = link k (Tip k x) p t+  | zero k m      = Bin p m (insertWithKey f k x l) r+  | otherwise     = Bin p m l (insertWithKey f k x r)+insertWithKey f k x t@(Tip ky y)+  | k == ky       = Tip k (f k x y)+  | otherwise     = link k (Tip k x) ky t+insertWithKey _ k x Nil = Tip k x++-- | \(O(\min(n,W))\). The expression (@'insertLookupWithKey' f k x map@)+-- is a pair where the first element is equal to (@'lookup' k map@)+-- and the second element equal to (@'insertWithKey' f k x map@).+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > insertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])+-- > insertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])+-- > insertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")+--+-- This is how to define @insertLookup@ using @insertLookupWithKey@:+--+-- > let insertLookup kx x t = insertLookupWithKey (\_ a _ -> a) kx x t+-- > insertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])+-- > insertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])++insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> Word64Map a -> (Maybe a, Word64Map a)+insertLookupWithKey f !k x t@(Bin p m l r)+  | nomatch k p m = (Nothing,link k (Tip k x) p t)+  | zero k m      = let (found,l') = insertLookupWithKey f k x l+                    in (found,Bin p m l' r)+  | otherwise     = let (found,r') = insertLookupWithKey f k x r+                    in (found,Bin p m l r')+insertLookupWithKey f k x t@(Tip ky y)+  | k == ky       = (Just y,Tip k (f k x y))+  | otherwise     = (Nothing,link k (Tip k x) ky t)+insertLookupWithKey _ k x Nil = (Nothing,Tip k x)+++{--------------------------------------------------------------------+  Deletion+--------------------------------------------------------------------}+-- | \(O(\min(n,W))\). Delete a key and its value from the map. When the key is not+-- a member of the map, the original map is returned.+--+-- > delete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"+-- > delete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]+-- > delete 5 empty                         == empty++delete :: Key -> Word64Map a -> Word64Map a+delete !k t@(Bin p m l r)+  | nomatch k p m = t+  | zero k m      = binCheckLeft p m (delete k l) r+  | otherwise     = binCheckRight p m l (delete k r)+delete k t@(Tip ky _)+  | k == ky       = Nil+  | otherwise     = t+delete _k Nil = Nil++-- | \(O(\min(n,W))\). Adjust a value at a specific key. When the key is not+-- a member of the map, the original map is returned.+--+-- > adjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]+-- > adjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]+-- > adjust ("new " ++) 7 empty                         == empty++adjust ::  (a -> a) -> Key -> Word64Map a -> Word64Map a+adjust f k m+  = adjustWithKey (\_ x -> f x) k m++-- | \(O(\min(n,W))\). Adjust a value at a specific key. When the key is not+-- a member of the map, the original map is returned.+--+-- > let f key x = (show key) ++ ":new " ++ x+-- > adjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]+-- > adjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]+-- > adjustWithKey f 7 empty                         == empty++adjustWithKey ::  (Key -> a -> a) -> Key -> Word64Map a -> Word64Map a+adjustWithKey f !k (Bin p m l r)+  | zero k m      = Bin p m (adjustWithKey f k l) r+  | otherwise     = Bin p m l (adjustWithKey f k r)+adjustWithKey f k t@(Tip ky y)+  | k == ky       = Tip ky (f k y)+  | otherwise     = t+adjustWithKey _ _ Nil = Nil+++-- | \(O(\min(n,W))\). The expression (@'update' f k map@) updates the value @x@+-- at @k@ (if it is in the map). If (@f x@) is 'Nothing', the element is+-- deleted. If it is (@'Just' y@), the key @k@ is bound to the new value @y@.+--+-- > let f x = if x == "a" then Just "new a" else Nothing+-- > update f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]+-- > update f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]+-- > update f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"++update ::  (a -> Maybe a) -> Key -> Word64Map a -> Word64Map a+update f+  = updateWithKey (\_ x -> f x)++-- | \(O(\min(n,W))\). The expression (@'update' f k map@) updates the value @x@+-- at @k@ (if it is in the map). If (@f k x@) is 'Nothing', the element is+-- deleted. If it is (@'Just' y@), the key @k@ is bound to the new value @y@.+--+-- > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing+-- > updateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]+-- > updateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]+-- > updateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"++updateWithKey ::  (Key -> a -> Maybe a) -> Key -> Word64Map a -> Word64Map a+updateWithKey f !k (Bin p m l r)+  | zero k m      = binCheckLeft p m (updateWithKey f k l) r+  | otherwise     = binCheckRight p m l (updateWithKey f k r)+updateWithKey f k t@(Tip ky y)+  | k == ky       = case (f k y) of+                      Just y' -> Tip ky y'+                      Nothing -> Nil+  | otherwise     = t+updateWithKey _ _ Nil = Nil++-- | \(O(\min(n,W))\). Lookup and update.+-- The function returns original value, if it is updated.+-- This is different behavior than 'Data.Map.updateLookupWithKey'.+-- Returns the original key value if the map entry is deleted.+--+-- > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing+-- > updateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:new a")])+-- > updateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])+-- > updateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")++updateLookupWithKey ::  (Key -> a -> Maybe a) -> Key -> Word64Map a -> (Maybe a,Word64Map a)+updateLookupWithKey f !k (Bin p m l r)+  | zero k m      = let !(found,l') = updateLookupWithKey f k l+                    in (found,binCheckLeft p m l' r)+  | otherwise     = let !(found,r') = updateLookupWithKey f k r+                    in (found,binCheckRight p m l r')+updateLookupWithKey f k t@(Tip ky y)+  | k==ky         = case (f k y) of+                      Just y' -> (Just y,Tip ky y')+                      Nothing -> (Just y,Nil)+  | otherwise     = (Nothing,t)+updateLookupWithKey _ _ Nil = (Nothing,Nil)++++-- | \(O(\min(n,W))\). The expression (@'alter' f k map@) alters the value @x@ at @k@, or absence thereof.+-- 'alter' can be used to insert, delete, or update a value in an 'Word64Map'.+-- In short : @'lookup' k ('alter' f k m) = f ('lookup' k m)@.+alter :: (Maybe a -> Maybe a) -> Key -> Word64Map a -> Word64Map a+alter f !k t@(Bin p m l r)+  | nomatch k p m = case f Nothing of+                      Nothing -> t+                      Just x -> link k (Tip k x) p t+  | zero k m      = binCheckLeft p m (alter f k l) r+  | otherwise     = binCheckRight p m l (alter f k r)+alter f k t@(Tip ky y)+  | k==ky         = case f (Just y) of+                      Just x -> Tip ky x+                      Nothing -> Nil+  | otherwise     = case f Nothing of+                      Just x -> link k (Tip k x) ky t+                      Nothing -> Tip ky y+alter f k Nil     = case f Nothing of+                      Just x -> Tip k x+                      Nothing -> Nil++-- | \(O(\min(n,W))\). The expression (@'alterF' f k map@) alters the value @x@ at+-- @k@, or absence thereof.  'alterF' can be used to inspect, insert, delete,+-- or update a value in an 'Word64Map'.  In short : @'lookup' k <$> 'alterF' f k m = f+-- ('lookup' k m)@.+--+-- Example:+--+-- @+-- interactiveAlter :: Int -> Word64Map String -> IO (Word64Map String)+-- interactiveAlter k m = alterF f k m where+--   f Nothing = do+--      putStrLn $ show k +++--          " was not found in the map. Would you like to add it?"+--      getUserResponse1 :: IO (Maybe String)+--   f (Just old) = do+--      putStrLn $ "The key is currently bound to " ++ show old +++--          ". Would you like to change or delete it?"+--      getUserResponse2 :: IO (Maybe String)+-- @+--+-- 'alterF' is the most general operation for working with an individual+-- key that may or may not be in a given map.+--+-- Note: 'alterF' is a flipped version of the @at@ combinator from+-- @Control.Lens.At@.+--+-- @since 0.5.8++alterF :: Functor f+       => (Maybe a -> f (Maybe a)) -> Key -> Word64Map a -> f (Word64Map a)+-- This implementation was stolen from 'Control.Lens.At'.+alterF f k m = (<$> f mv) $ \fres ->+  case fres of+    Nothing -> maybe m (const (delete k m)) mv+    Just v' -> insert k v' m+  where mv = lookup k m++{--------------------------------------------------------------------+  Union+--------------------------------------------------------------------}+-- | The union of a list of maps.+--+-- > unions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]+-- >     == fromList [(3, "b"), (5, "a"), (7, "C")]+-- > unions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]+-- >     == fromList [(3, "B3"), (5, "A3"), (7, "C")]++unions :: Foldable f => f (Word64Map a) -> Word64Map a+unions xs+  = Foldable.foldl' union empty xs++-- | The union of a list of maps, with a combining operation.+--+-- > unionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]+-- >     == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]++unionsWith :: Foldable f => (a->a->a) -> f (Word64Map a) -> Word64Map a+unionsWith f ts+  = Foldable.foldl' (unionWith f) empty ts++-- | \(O(n+m)\). The (left-biased) union of two maps.+-- It prefers the first map when duplicate keys are encountered,+-- i.e. (@'union' == 'unionWith' 'const'@).+--+-- > union (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]++union :: Word64Map a -> Word64Map a -> Word64Map a+union m1 m2+  = mergeWithKey' Bin const id id m1 m2++-- | \(O(n+m)\). The union with a combining function.+--+-- > unionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]++unionWith :: (a -> a -> a) -> Word64Map a -> Word64Map a -> Word64Map a+unionWith f m1 m2+  = unionWithKey (\_ x y -> f x y) m1 m2++-- | \(O(n+m)\). The union with a combining function.+--+-- > let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value+-- > unionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]++unionWithKey :: (Key -> a -> a -> a) -> Word64Map a -> Word64Map a -> Word64Map a+unionWithKey f m1 m2+  = mergeWithKey' Bin (\(Tip k1 x1) (Tip _k2 x2) -> Tip k1 (f k1 x1 x2)) id id m1 m2++{--------------------------------------------------------------------+  Difference+--------------------------------------------------------------------}+-- | \(O(n+m)\). Difference between two maps (based on keys).+--+-- > difference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"++difference :: Word64Map a -> Word64Map b -> Word64Map a+difference m1 m2+  = mergeWithKey (\_ _ _ -> Nothing) id (const Nil) m1 m2++-- | \(O(n+m)\). Difference with a combining function.+--+-- > let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing+-- > differenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])+-- >     == singleton 3 "b:B"++differenceWith :: (a -> b -> Maybe a) -> Word64Map a -> Word64Map b -> Word64Map a+differenceWith f m1 m2+  = differenceWithKey (\_ x y -> f x y) m1 m2++-- | \(O(n+m)\). Difference with a combining function. When two equal keys are+-- encountered, the combining function is applied to the key and both values.+-- If it returns 'Nothing', the element is discarded (proper set difference).+-- If it returns (@'Just' y@), the element is updated with a new value @y@.+--+-- > let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing+-- > differenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])+-- >     == singleton 3 "3:b|B"++differenceWithKey :: (Key -> a -> b -> Maybe a) -> Word64Map a -> Word64Map b -> Word64Map a+differenceWithKey f m1 m2+  = mergeWithKey f id (const Nil) m1 m2+++-- TODO(wrengr): re-verify that asymptotic bound+-- | \(O(n+m)\). Remove all the keys in a given set from a map.+--+-- @+-- m \`withoutKeys\` s = 'filterWithKey' (\\k _ -> k ``Word64Set.notMember`` s) m+-- @+--+-- @since 0.5.8+withoutKeys :: Word64Map a -> Word64Set.Word64Set -> Word64Map a+withoutKeys t1@(Bin p1 m1 l1 r1) t2@(Word64Set.Bin p2 m2 l2 r2)+    | shorter m1 m2  = difference1+    | shorter m2 m1  = difference2+    | p1 == p2       = bin p1 m1 (withoutKeys l1 l2) (withoutKeys r1 r2)+    | otherwise      = t1+    where+    difference1+        | nomatch p2 p1 m1  = t1+        | zero p2 m1        = binCheckLeft p1 m1 (withoutKeys l1 t2) r1+        | otherwise         = binCheckRight p1 m1 l1 (withoutKeys r1 t2)+    difference2+        | nomatch p1 p2 m2  = t1+        | zero p1 m2        = withoutKeys t1 l2+        | otherwise         = withoutKeys t1 r2+withoutKeys t1@(Bin p1 m1 _ _) (Word64Set.Tip p2 bm2) =+    let minbit = bitmapOf p1+        lt_minbit = minbit - 1+        maxbit = bitmapOf (p1 .|. (m1 .|. (m1 - 1)))+        gt_maxbit = (-maxbit) `xor` maxbit+    -- TODO(wrengr): should we manually inline/unroll 'updatePrefix'+    -- and 'withoutBM' here, in order to avoid redundant case analyses?+    in updatePrefix p2 t1 $ withoutBM (bm2 .|. lt_minbit .|. gt_maxbit)+withoutKeys t1@(Bin _ _ _ _) Word64Set.Nil = t1+withoutKeys t1@(Tip k1 _) t2+    | k1 `Word64Set.member` t2 = Nil+    | otherwise = t1+withoutKeys Nil _ = Nil+++updatePrefix+    :: Word64SetPrefix -> Word64Map a -> (Word64Map a -> Word64Map a) -> Word64Map a+updatePrefix !kp t@(Bin p m l r) f+    | m .&. Word64Set.suffixBitMask /= 0 =+        if p .&. Word64Set.prefixBitMask == kp then f t else t+    | nomatch kp p m = t+    | zero kp m      = binCheckLeft p m (updatePrefix kp l f) r+    | otherwise      = binCheckRight p m l (updatePrefix kp r f)+updatePrefix kp t@(Tip kx _) f+    | kx .&. Word64Set.prefixBitMask == kp = f t+    | otherwise = t+updatePrefix _ Nil _ = Nil+++withoutBM :: Word64SetBitMap -> Word64Map a -> Word64Map a+withoutBM 0 t = t+withoutBM bm (Bin p m l r) =+    let leftBits = bitmapOf (p .|. m) - 1+        bmL = bm .&. leftBits+        bmR = bm `xor` bmL -- = (bm .&. complement leftBits)+    in  bin p m (withoutBM bmL l) (withoutBM bmR r)+withoutBM bm t@(Tip k _)+    -- TODO(wrengr): need we manually inline 'Word64Set.Member' here?+    | k `Word64Set.member` Word64Set.Tip (k .&. Word64Set.prefixBitMask) bm = Nil+    | otherwise = t+withoutBM _ Nil = Nil+++{--------------------------------------------------------------------+  Intersection+--------------------------------------------------------------------}+-- | \(O(n+m)\). The (left-biased) intersection of two maps (based on keys).+--+-- > intersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"++intersection :: Word64Map a -> Word64Map b -> Word64Map a+intersection m1 m2+  = mergeWithKey' bin const (const Nil) (const Nil) m1 m2+++-- TODO(wrengr): re-verify that asymptotic bound+-- | \(O(n+m)\). The restriction of a map to the keys in a set.+--+-- @+-- m \`restrictKeys\` s = 'filterWithKey' (\\k _ -> k ``Word64Set.member`` s) m+-- @+--+-- @since 0.5.8+restrictKeys :: Word64Map a -> Word64Set.Word64Set -> Word64Map a+restrictKeys t1@(Bin p1 m1 l1 r1) t2@(Word64Set.Bin p2 m2 l2 r2)+    | shorter m1 m2  = intersection1+    | shorter m2 m1  = intersection2+    | p1 == p2       = bin p1 m1 (restrictKeys l1 l2) (restrictKeys r1 r2)+    | otherwise      = Nil+    where+    intersection1+        | nomatch p2 p1 m1  = Nil+        | zero p2 m1        = restrictKeys l1 t2+        | otherwise         = restrictKeys r1 t2+    intersection2+        | nomatch p1 p2 m2  = Nil+        | zero p1 m2        = restrictKeys t1 l2+        | otherwise         = restrictKeys t1 r2+restrictKeys t1@(Bin p1 m1 _ _) (Word64Set.Tip p2 bm2) =+    let minbit = bitmapOf p1+        ge_minbit = complement (minbit - 1)+        maxbit = bitmapOf (p1 .|. (m1 .|. (m1 - 1)))+        le_maxbit = maxbit .|. (maxbit - 1)+    -- TODO(wrengr): should we manually inline/unroll 'lookupPrefix'+    -- and 'restrictBM' here, in order to avoid redundant case analyses?+    in restrictBM (bm2 .&. ge_minbit .&. le_maxbit) (lookupPrefix p2 t1)+restrictKeys (Bin _ _ _ _) Word64Set.Nil = Nil+restrictKeys t1@(Tip k1 _) t2+    | k1 `Word64Set.member` t2 = t1+    | otherwise = Nil+restrictKeys Nil _ = Nil+++-- | \(O(\min(n,W))\). Restrict to the sub-map with all keys matching+-- a key prefix.+lookupPrefix :: Word64SetPrefix -> Word64Map a -> Word64Map a+lookupPrefix !kp t@(Bin p m l r)+    | m .&. Word64Set.suffixBitMask /= 0 =+        if p .&. Word64Set.prefixBitMask == kp then t else Nil+    | nomatch kp p m = Nil+    | zero kp m      = lookupPrefix kp l+    | otherwise      = lookupPrefix kp r+lookupPrefix kp t@(Tip kx _)+    | (kx .&. Word64Set.prefixBitMask) == kp = t+    | otherwise = Nil+lookupPrefix _ Nil = Nil+++restrictBM :: Word64SetBitMap -> Word64Map a -> Word64Map a+restrictBM 0 _ = Nil+restrictBM bm (Bin p m l r) =+    let leftBits = bitmapOf (p .|. m) - 1+        bmL = bm .&. leftBits+        bmR = bm `xor` bmL -- = (bm .&. complement leftBits)+    in  bin p m (restrictBM bmL l) (restrictBM bmR r)+restrictBM bm t@(Tip k _)+    -- TODO(wrengr): need we manually inline 'Word64Set.Member' here?+    | k `Word64Set.member` Word64Set.Tip (k .&. Word64Set.prefixBitMask) bm = t+    | otherwise = Nil+restrictBM _ Nil = Nil+++-- | \(O(n+m)\). The intersection with a combining function.+--+-- > intersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"++intersectionWith :: (a -> b -> c) -> Word64Map a -> Word64Map b -> Word64Map c+intersectionWith f m1 m2+  = intersectionWithKey (\_ x y -> f x y) m1 m2++-- | \(O(n+m)\). The intersection with a combining function.+--+-- > let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar+-- > intersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"++intersectionWithKey :: (Key -> a -> b -> c) -> Word64Map a -> Word64Map b -> Word64Map c+intersectionWithKey f m1 m2+  = mergeWithKey' bin (\(Tip k1 x1) (Tip _k2 x2) -> Tip k1 (f k1 x1 x2)) (const Nil) (const Nil) m1 m2++{--------------------------------------------------------------------+  MergeWithKey+--------------------------------------------------------------------}++-- | \(O(n+m)\). A high-performance universal combining function. Using+-- 'mergeWithKey', all combining functions can be defined without any loss of+-- efficiency (with exception of 'union', 'difference' and 'intersection',+-- where sharing of some nodes is lost with 'mergeWithKey').+--+-- Please make sure you know what is going on when using 'mergeWithKey',+-- otherwise you can be surprised by unexpected code growth or even+-- corruption of the data structure.+--+-- When 'mergeWithKey' is given three arguments, it is inlined to the call+-- site. You should therefore use 'mergeWithKey' only to define your custom+-- combining functions. For example, you could define 'unionWithKey',+-- 'differenceWithKey' and 'intersectionWithKey' as+--+-- > myUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -> Just (f k x1 x2)) id id m1 m2+-- > myDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2+-- > myIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -> Just (f k x1 x2)) (const empty) (const empty) m1 m2+--+-- When calling @'mergeWithKey' combine only1 only2@, a function combining two+-- 'Word64Map's is created, such that+--+-- * if a key is present in both maps, it is passed with both corresponding+--   values to the @combine@ function. Depending on the result, the key is either+--   present in the result with specified value, or is left out;+--+-- * a nonempty subtree present only in the first map is passed to @only1@ and+--   the output is added to the result;+--+-- * a nonempty subtree present only in the second map is passed to @only2@ and+--   the output is added to the result.+--+-- The @only1@ and @only2@ methods /must return a map with a subset (possibly empty) of the keys of the given map/.+-- The values can be modified arbitrarily. Most common variants of @only1@ and+-- @only2@ are 'id' and @'const' 'empty'@, but for example @'map' f@ or+-- @'filterWithKey' f@ could be used for any @f@.++mergeWithKey :: (Key -> a -> b -> Maybe c) -> (Word64Map a -> Word64Map c) -> (Word64Map b -> Word64Map c)+             -> Word64Map a -> Word64Map b -> Word64Map c+mergeWithKey f g1 g2 = mergeWithKey' bin combine g1 g2+  where -- We use the lambda form to avoid non-exhaustive pattern matches warning.+        combine = \(Tip k1 x1) (Tip _k2 x2) ->+          case f k1 x1 x2 of+            Nothing -> Nil+            Just x -> Tip k1 x+        {-# INLINE combine #-}+{-# INLINE mergeWithKey #-}++-- Slightly more general version of mergeWithKey. It differs in the following:+--+-- * the combining function operates on maps instead of keys and values. The+--   reason is to enable sharing in union, difference and intersection.+--+-- * mergeWithKey' is given an equivalent of bin. The reason is that in union*,+--   Bin constructor can be used, because we know both subtrees are nonempty.++mergeWithKey' :: (Prefix -> Mask -> Word64Map c -> Word64Map c -> Word64Map c)+              -> (Word64Map a -> Word64Map b -> Word64Map c) -> (Word64Map a -> Word64Map c) -> (Word64Map b -> Word64Map c)+              -> Word64Map a -> Word64Map b -> Word64Map c+mergeWithKey' bin' f g1 g2 = go+  where+    go t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)+      | shorter m1 m2  = merge1+      | shorter m2 m1  = merge2+      | p1 == p2       = bin' p1 m1 (go l1 l2) (go r1 r2)+      | otherwise      = maybe_link p1 (g1 t1) p2 (g2 t2)+      where+        merge1 | nomatch p2 p1 m1  = maybe_link p1 (g1 t1) p2 (g2 t2)+               | zero p2 m1        = bin' p1 m1 (go l1 t2) (g1 r1)+               | otherwise         = bin' p1 m1 (g1 l1) (go r1 t2)+        merge2 | nomatch p1 p2 m2  = maybe_link p1 (g1 t1) p2 (g2 t2)+               | zero p1 m2        = bin' p2 m2 (go t1 l2) (g2 r2)+               | otherwise         = bin' p2 m2 (g2 l2) (go t1 r2)++    go t1'@(Bin _ _ _ _) t2'@(Tip k2' _) = merge0 t2' k2' t1'+      where+        merge0 t2 k2 t1@(Bin p1 m1 l1 r1)+          | nomatch k2 p1 m1 = maybe_link p1 (g1 t1) k2 (g2 t2)+          | zero k2 m1 = bin' p1 m1 (merge0 t2 k2 l1) (g1 r1)+          | otherwise  = bin' p1 m1 (g1 l1) (merge0 t2 k2 r1)+        merge0 t2 k2 t1@(Tip k1 _)+          | k1 == k2 = f t1 t2+          | otherwise = maybe_link k1 (g1 t1) k2 (g2 t2)+        merge0 t2 _  Nil = g2 t2++    go t1@(Bin _ _ _ _) Nil = g1 t1++    go t1'@(Tip k1' _) t2' = merge0 t1' k1' t2'+      where+        merge0 t1 k1 t2@(Bin p2 m2 l2 r2)+          | nomatch k1 p2 m2 = maybe_link k1 (g1 t1) p2 (g2 t2)+          | zero k1 m2 = bin' p2 m2 (merge0 t1 k1 l2) (g2 r2)+          | otherwise  = bin' p2 m2 (g2 l2) (merge0 t1 k1 r2)+        merge0 t1 k1 t2@(Tip k2 _)+          | k1 == k2 = f t1 t2+          | otherwise = maybe_link k1 (g1 t1) k2 (g2 t2)+        merge0 t1 _  Nil = g1 t1++    go Nil t2 = g2 t2++    maybe_link _ Nil _ t2 = t2+    maybe_link _ t1 _ Nil = t1+    maybe_link p1 t1 p2 t2 = link p1 t1 p2 t2+    {-# INLINE maybe_link #-}+{-# INLINE mergeWithKey' #-}+++{--------------------------------------------------------------------+  mergeA+--------------------------------------------------------------------}++-- | A tactic for dealing with keys present in one map but not the+-- other in 'merge' or 'mergeA'.+--+-- A tactic of type @WhenMissing f k x z@ is an abstract representation+-- of a function of type @Key -> x -> f (Maybe z)@.+--+-- @since 0.5.9++data WhenMissing f x y = WhenMissing+  { missingSubtree :: Word64Map x -> f (Word64Map y)+  , missingKey :: Key -> x -> f (Maybe y)}++-- | @since 0.5.9+instance (Applicative f, Monad f) => Functor (WhenMissing f x) where+  fmap = mapWhenMissing+  {-# INLINE fmap #-}+++-- | @since 0.5.9+instance (Applicative f, Monad f) => Category.Category (WhenMissing f)+  where+    id = preserveMissing+    f . g =+      traverseMaybeMissing $ \ k x -> do+        y <- missingKey g k x+        case y of+          Nothing -> pure Nothing+          Just q  -> missingKey f k q+    {-# INLINE id #-}+    {-# INLINE (.) #-}+++-- | Equivalent to @ReaderT k (ReaderT x (MaybeT f))@.+--+-- @since 0.5.9+instance (Applicative f, Monad f) => Applicative (WhenMissing f x) where+  pure x = mapMissing (\ _ _ -> x)+  f <*> g =+    traverseMaybeMissing $ \k x -> do+      res1 <- missingKey f k x+      case res1 of+        Nothing -> pure Nothing+        Just r  -> (pure $!) . fmap r =<< missingKey g k x+  {-# INLINE pure #-}+  {-# INLINE (<*>) #-}+++-- | Equivalent to @ReaderT k (ReaderT x (MaybeT f))@.+--+-- @since 0.5.9+instance (Applicative f, Monad f) => Monad (WhenMissing f x) where+  m >>= f =+    traverseMaybeMissing $ \k x -> do+      res1 <- missingKey m k x+      case res1 of+        Nothing -> pure Nothing+        Just r  -> missingKey (f r) k x+  {-# INLINE (>>=) #-}+++-- | Map covariantly over a @'WhenMissing' f x@.+--+-- @since 0.5.9+mapWhenMissing+  :: (Applicative f, Monad f)+  => (a -> b)+  -> WhenMissing f x a+  -> WhenMissing f x b+mapWhenMissing f t = WhenMissing+  { missingSubtree = \m -> missingSubtree t m >>= \m' -> pure $! fmap f m'+  , missingKey     = \k x -> missingKey t k x >>= \q -> (pure $! fmap f q) }+{-# INLINE mapWhenMissing #-}+++-- | Map covariantly over a @'WhenMissing' f x@, using only a+-- 'Functor f' constraint.+mapGentlyWhenMissing+  :: Functor f+  => (a -> b)+  -> WhenMissing f x a+  -> WhenMissing f x b+mapGentlyWhenMissing f t = WhenMissing+  { missingSubtree = \m -> fmap f <$> missingSubtree t m+  , missingKey     = \k x -> fmap f <$> missingKey t k x }+{-# INLINE mapGentlyWhenMissing #-}+++-- | Map covariantly over a @'WhenMatched' f k x@, using only a+-- 'Functor f' constraint.+mapGentlyWhenMatched+  :: Functor f+  => (a -> b)+  -> WhenMatched f x y a+  -> WhenMatched f x y b+mapGentlyWhenMatched f t =+  zipWithMaybeAMatched $ \k x y -> fmap f <$> runWhenMatched t k x y+{-# INLINE mapGentlyWhenMatched #-}+++-- | Map contravariantly over a @'WhenMissing' f _ x@.+--+-- @since 0.5.9+lmapWhenMissing :: (b -> a) -> WhenMissing f a x -> WhenMissing f b x+lmapWhenMissing f t = WhenMissing+  { missingSubtree = \m -> missingSubtree t (fmap f m)+  , missingKey     = \k x -> missingKey t k (f x) }+{-# INLINE lmapWhenMissing #-}+++-- | Map contravariantly over a @'WhenMatched' f _ y z@.+--+-- @since 0.5.9+contramapFirstWhenMatched+  :: (b -> a)+  -> WhenMatched f a y z+  -> WhenMatched f b y z+contramapFirstWhenMatched f t =+  WhenMatched $ \k x y -> runWhenMatched t k (f x) y+{-# INLINE contramapFirstWhenMatched #-}+++-- | Map contravariantly over a @'WhenMatched' f x _ z@.+--+-- @since 0.5.9+contramapSecondWhenMatched+  :: (b -> a)+  -> WhenMatched f x a z+  -> WhenMatched f x b z+contramapSecondWhenMatched f t =+  WhenMatched $ \k x y -> runWhenMatched t k x (f y)+{-# INLINE contramapSecondWhenMatched #-}+++-- | A tactic for dealing with keys present in one map but not the+-- other in 'merge'.+--+-- A tactic of type @SimpleWhenMissing x z@ is an abstract+-- representation of a function of type @Key -> x -> Maybe z@.+--+-- @since 0.5.9+type SimpleWhenMissing = WhenMissing Identity+++-- | A tactic for dealing with keys present in both maps in 'merge'+-- or 'mergeA'.+--+-- A tactic of type @WhenMatched f x y z@ is an abstract representation+-- of a function of type @Key -> x -> y -> f (Maybe z)@.+--+-- @since 0.5.9+newtype WhenMatched f x y z = WhenMatched+  { matchedKey :: Key -> x -> y -> f (Maybe z) }+++-- | Along with zipWithMaybeAMatched, witnesses the isomorphism+-- between @WhenMatched f x y z@ and @Key -> x -> y -> f (Maybe z)@.+--+-- @since 0.5.9+runWhenMatched :: WhenMatched f x y z -> Key -> x -> y -> f (Maybe z)+runWhenMatched = matchedKey+{-# INLINE runWhenMatched #-}+++-- | Along with traverseMaybeMissing, witnesses the isomorphism+-- between @WhenMissing f x y@ and @Key -> x -> f (Maybe y)@.+--+-- @since 0.5.9+runWhenMissing :: WhenMissing f x y -> Key-> x -> f (Maybe y)+runWhenMissing = missingKey+{-# INLINE runWhenMissing #-}+++-- | @since 0.5.9+instance Functor f => Functor (WhenMatched f x y) where+  fmap = mapWhenMatched+  {-# INLINE fmap #-}+++-- | @since 0.5.9+instance (Monad f, Applicative f) => Category.Category (WhenMatched f x)+  where+    id = zipWithMatched (\_ _ y -> y)+    f . g =+      zipWithMaybeAMatched $ \k x y -> do+        res <- runWhenMatched g k x y+        case res of+          Nothing -> pure Nothing+          Just r  -> runWhenMatched f k x r+    {-# INLINE id #-}+    {-# INLINE (.) #-}+++-- | Equivalent to @ReaderT Key (ReaderT x (ReaderT y (MaybeT f)))@+--+-- @since 0.5.9+instance (Monad f, Applicative f) => Applicative (WhenMatched f x y) where+  pure x = zipWithMatched (\_ _ _ -> x)+  fs <*> xs =+    zipWithMaybeAMatched $ \k x y -> do+      res <- runWhenMatched fs k x y+      case res of+        Nothing -> pure Nothing+        Just r  -> (pure $!) . fmap r =<< runWhenMatched xs k x y+  {-# INLINE pure #-}+  {-# INLINE (<*>) #-}+++-- | Equivalent to @ReaderT Key (ReaderT x (ReaderT y (MaybeT f)))@+--+-- @since 0.5.9+instance (Monad f, Applicative f) => Monad (WhenMatched f x y) where+  m >>= f =+    zipWithMaybeAMatched $ \k x y -> do+      res <- runWhenMatched m k x y+      case res of+        Nothing -> pure Nothing+        Just r  -> runWhenMatched (f r) k x y+  {-# INLINE (>>=) #-}+++-- | Map covariantly over a @'WhenMatched' f x y@.+--+-- @since 0.5.9+mapWhenMatched+  :: Functor f+  => (a -> b)+  -> WhenMatched f x y a+  -> WhenMatched f x y b+mapWhenMatched f (WhenMatched g) =+  WhenMatched $ \k x y -> fmap (fmap f) (g k x y)+{-# INLINE mapWhenMatched #-}+++-- | A tactic for dealing with keys present in both maps in 'merge'.+--+-- A tactic of type @SimpleWhenMatched x y z@ is an abstract+-- representation of a function of type @Key -> x -> y -> Maybe z@.+--+-- @since 0.5.9+type SimpleWhenMatched = WhenMatched Identity+++-- | When a key is found in both maps, apply a function to the key+-- and values and use the result in the merged map.+--+-- > zipWithMatched+-- >   :: (Key -> x -> y -> z)+-- >   -> SimpleWhenMatched x y z+--+-- @since 0.5.9+zipWithMatched+  :: Applicative f+  => (Key -> x -> y -> z)+  -> WhenMatched f x y z+zipWithMatched f = WhenMatched $ \ k x y -> pure . Just $ f k x y+{-# INLINE zipWithMatched #-}+++-- | When a key is found in both maps, apply a function to the key+-- and values to produce an action and use its result in the merged+-- map.+--+-- @since 0.5.9+zipWithAMatched+  :: Applicative f+  => (Key -> x -> y -> f z)+  -> WhenMatched f x y z+zipWithAMatched f = WhenMatched $ \ k x y -> Just <$> f k x y+{-# INLINE zipWithAMatched #-}+++-- | When a key is found in both maps, apply a function to the key+-- and values and maybe use the result in the merged map.+--+-- > zipWithMaybeMatched+-- >   :: (Key -> x -> y -> Maybe z)+-- >   -> SimpleWhenMatched x y z+--+-- @since 0.5.9+zipWithMaybeMatched+  :: Applicative f+  => (Key -> x -> y -> Maybe z)+  -> WhenMatched f x y z+zipWithMaybeMatched f = WhenMatched $ \ k x y -> pure $ f k x y+{-# INLINE zipWithMaybeMatched #-}+++-- | When a key is found in both maps, apply a function to the key+-- and values, perform the resulting action, and maybe use the+-- result in the merged map.+--+-- This is the fundamental 'WhenMatched' tactic.+--+-- @since 0.5.9+zipWithMaybeAMatched+  :: (Key -> x -> y -> f (Maybe z))+  -> WhenMatched f x y z+zipWithMaybeAMatched f = WhenMatched $ \ k x y -> f k x y+{-# INLINE zipWithMaybeAMatched #-}+++-- | Drop all the entries whose keys are missing from the other+-- map.+--+-- > dropMissing :: SimpleWhenMissing x y+--+-- prop> dropMissing = mapMaybeMissing (\_ _ -> Nothing)+--+-- but @dropMissing@ is much faster.+--+-- @since 0.5.9+dropMissing :: Applicative f => WhenMissing f x y+dropMissing = WhenMissing+  { missingSubtree = const (pure Nil)+  , missingKey     = \_ _ -> pure Nothing }+{-# INLINE dropMissing #-}+++-- | Preserve, unchanged, the entries whose keys are missing from+-- the other map.+--+-- > preserveMissing :: SimpleWhenMissing x x+--+-- prop> preserveMissing = Merge.Lazy.mapMaybeMissing (\_ x -> Just x)+--+-- but @preserveMissing@ is much faster.+--+-- @since 0.5.9+preserveMissing :: Applicative f => WhenMissing f x x+preserveMissing = WhenMissing+  { missingSubtree = pure+  , missingKey     = \_ v -> pure (Just v) }+{-# INLINE preserveMissing #-}+++-- | Map over the entries whose keys are missing from the other map.+--+-- > mapMissing :: (k -> x -> y) -> SimpleWhenMissing x y+--+-- prop> mapMissing f = mapMaybeMissing (\k x -> Just $ f k x)+--+-- but @mapMissing@ is somewhat faster.+--+-- @since 0.5.9+mapMissing :: Applicative f => (Key -> x -> y) -> WhenMissing f x y+mapMissing f = WhenMissing+  { missingSubtree = \m -> pure $! mapWithKey f m+  , missingKey     = \k x -> pure $ Just (f k x) }+{-# INLINE mapMissing #-}+++-- | Map over the entries whose keys are missing from the other+-- map, optionally removing some. This is the most powerful+-- 'SimpleWhenMissing' tactic, but others are usually more efficient.+--+-- > mapMaybeMissing :: (Key -> x -> Maybe y) -> SimpleWhenMissing x y+--+-- prop> mapMaybeMissing f = traverseMaybeMissing (\k x -> pure (f k x))+--+-- but @mapMaybeMissing@ uses fewer unnecessary 'Applicative'+-- operations.+--+-- @since 0.5.9+mapMaybeMissing+  :: Applicative f => (Key -> x -> Maybe y) -> WhenMissing f x y+mapMaybeMissing f = WhenMissing+  { missingSubtree = \m -> pure $! mapMaybeWithKey f m+  , missingKey     = \k x -> pure $! f k x }+{-# INLINE mapMaybeMissing #-}+++-- | Filter the entries whose keys are missing from the other map.+--+-- > filterMissing :: (k -> x -> Bool) -> SimpleWhenMissing x x+--+-- prop> filterMissing f = Merge.Lazy.mapMaybeMissing $ \k x -> guard (f k x) *> Just x+--+-- but this should be a little faster.+--+-- @since 0.5.9+filterMissing+  :: Applicative f => (Key -> x -> Bool) -> WhenMissing f x x+filterMissing f = WhenMissing+  { missingSubtree = \m -> pure $! filterWithKey f m+  , missingKey     = \k x -> pure $! if f k x then Just x else Nothing }+{-# INLINE filterMissing #-}+++-- | Filter the entries whose keys are missing from the other map+-- using some 'Applicative' action.+--+-- > filterAMissing f = Merge.Lazy.traverseMaybeMissing $+-- >   \k x -> (\b -> guard b *> Just x) <$> f k x+--+-- but this should be a little faster.+--+-- @since 0.5.9+filterAMissing+  :: Applicative f => (Key -> x -> f Bool) -> WhenMissing f x x+filterAMissing f = WhenMissing+  { missingSubtree = \m -> filterWithKeyA f m+  , missingKey     = \k x -> bool Nothing (Just x) <$> f k x }+{-# INLINE filterAMissing #-}+++-- | \(O(n)\). Filter keys and values using an 'Applicative' predicate.+filterWithKeyA+  :: Applicative f => (Key -> a -> f Bool) -> Word64Map a -> f (Word64Map a)+filterWithKeyA _ Nil           = pure Nil+filterWithKeyA f t@(Tip k x)   = (\b -> if b then t else Nil) <$> f k x+filterWithKeyA f (Bin p m l r)+  | m < 0     = liftA2 (flip (bin p m)) (filterWithKeyA f r) (filterWithKeyA f l)+  | otherwise = liftA2 (bin p m) (filterWithKeyA f l) (filterWithKeyA f r)++-- | This wasn't in Data.Bool until 4.7.0, so we define it here+bool :: a -> a -> Bool -> a+bool f _ False = f+bool _ t True  = t+++-- | Traverse over the entries whose keys are missing from the other+-- map.+--+-- @since 0.5.9+traverseMissing+  :: Applicative f => (Key -> x -> f y) -> WhenMissing f x y+traverseMissing f = WhenMissing+  { missingSubtree = traverseWithKey f+  , missingKey = \k x -> Just <$> f k x }+{-# INLINE traverseMissing #-}+++-- | Traverse over the entries whose keys are missing from the other+-- map, optionally producing values to put in the result. This is+-- the most powerful 'WhenMissing' tactic, but others are usually+-- more efficient.+--+-- @since 0.5.9+traverseMaybeMissing+  :: Applicative f => (Key -> x -> f (Maybe y)) -> WhenMissing f x y+traverseMaybeMissing f = WhenMissing+  { missingSubtree = traverseMaybeWithKey f+  , missingKey = f }+{-# INLINE traverseMaybeMissing #-}+++-- | \(O(n)\). Traverse keys\/values and collect the 'Just' results.+--+-- @since 0.6.4+traverseMaybeWithKey+  :: Applicative f => (Key -> a -> f (Maybe b)) -> Word64Map a -> f (Word64Map b)+traverseMaybeWithKey f = go+    where+    go Nil           = pure Nil+    go (Tip k x)     = maybe Nil (Tip k) <$> f k x+    go (Bin p m l r)+      | m < 0     = liftA2 (flip (bin p m)) (go r) (go l)+      | otherwise = liftA2 (bin p m) (go l) (go r)+++-- | Merge two maps.+--+-- 'merge' takes two 'WhenMissing' tactics, a 'WhenMatched' tactic+-- and two maps. It uses the tactics to merge the maps. Its behavior+-- is best understood via its fundamental tactics, 'mapMaybeMissing'+-- and 'zipWithMaybeMatched'.+--+-- Consider+--+-- @+-- merge (mapMaybeMissing g1)+--              (mapMaybeMissing g2)+--              (zipWithMaybeMatched f)+--              m1 m2+-- @+--+-- Take, for example,+--+-- @+-- m1 = [(0, \'a\'), (1, \'b\'), (3, \'c\'), (4, \'d\')]+-- m2 = [(1, "one"), (2, "two"), (4, "three")]+-- @+--+-- 'merge' will first \"align\" these maps by key:+--+-- @+-- m1 = [(0, \'a\'), (1, \'b\'),               (3, \'c\'), (4, \'d\')]+-- m2 =           [(1, "one"), (2, "two"),           (4, "three")]+-- @+--+-- It will then pass the individual entries and pairs of entries+-- to @g1@, @g2@, or @f@ as appropriate:+--+-- @+-- maybes = [g1 0 \'a\', f 1 \'b\' "one", g2 2 "two", g1 3 \'c\', f 4 \'d\' "three"]+-- @+--+-- This produces a 'Maybe' for each key:+--+-- @+-- keys =     0        1          2           3        4+-- results = [Nothing, Just True, Just False, Nothing, Just True]+-- @+--+-- Finally, the @Just@ results are collected into a map:+--+-- @+-- return value = [(1, True), (2, False), (4, True)]+-- @+--+-- The other tactics below are optimizations or simplifications of+-- 'mapMaybeMissing' for special cases. Most importantly,+--+-- * 'dropMissing' drops all the keys.+-- * 'preserveMissing' leaves all the entries alone.+--+-- When 'merge' is given three arguments, it is inlined at the call+-- site. To prevent excessive inlining, you should typically use+-- 'merge' to define your custom combining functions.+--+--+-- Examples:+--+-- prop> unionWithKey f = merge preserveMissing preserveMissing (zipWithMatched f)+-- prop> intersectionWithKey f = merge dropMissing dropMissing (zipWithMatched f)+-- prop> differenceWith f = merge diffPreserve diffDrop f+-- prop> symmetricDifference = merge diffPreserve diffPreserve (\ _ _ _ -> Nothing)+-- prop> mapEachPiece f g h = merge (diffMapWithKey f) (diffMapWithKey g)+--+-- @since 0.5.9+merge+  :: SimpleWhenMissing a c -- ^ What to do with keys in @m1@ but not @m2@+  -> SimpleWhenMissing b c -- ^ What to do with keys in @m2@ but not @m1@+  -> SimpleWhenMatched a b c -- ^ What to do with keys in both @m1@ and @m2@+  -> Word64Map a -- ^ Map @m1@+  -> Word64Map b -- ^ Map @m2@+  -> Word64Map c+merge g1 g2 f m1 m2 =+  runIdentity $ mergeA g1 g2 f m1 m2+{-# INLINE merge #-}+++-- | An applicative version of 'merge'.+--+-- 'mergeA' takes two 'WhenMissing' tactics, a 'WhenMatched'+-- tactic and two maps. It uses the tactics to merge the maps.+-- Its behavior is best understood via its fundamental tactics,+-- 'traverseMaybeMissing' and 'zipWithMaybeAMatched'.+--+-- Consider+--+-- @+-- mergeA (traverseMaybeMissing g1)+--               (traverseMaybeMissing g2)+--               (zipWithMaybeAMatched f)+--               m1 m2+-- @+--+-- Take, for example,+--+-- @+-- m1 = [(0, \'a\'), (1, \'b\'), (3,\'c\'), (4, \'d\')]+-- m2 = [(1, "one"), (2, "two"), (4, "three")]+-- @+--+-- 'mergeA' will first \"align\" these maps by key:+--+-- @+-- m1 = [(0, \'a\'), (1, \'b\'),               (3, \'c\'), (4, \'d\')]+-- m2 =           [(1, "one"), (2, "two"),           (4, "three")]+-- @+--+-- It will then pass the individual entries and pairs of entries+-- to @g1@, @g2@, or @f@ as appropriate:+--+-- @+-- actions = [g1 0 \'a\', f 1 \'b\' "one", g2 2 "two", g1 3 \'c\', f 4 \'d\' "three"]+-- @+--+-- Next, it will perform the actions in the @actions@ list in order from+-- left to right.+--+-- @+-- keys =     0        1          2           3        4+-- results = [Nothing, Just True, Just False, Nothing, Just True]+-- @+--+-- Finally, the @Just@ results are collected into a map:+--+-- @+-- return value = [(1, True), (2, False), (4, True)]+-- @+--+-- The other tactics below are optimizations or simplifications of+-- 'traverseMaybeMissing' for special cases. Most importantly,+--+-- * 'dropMissing' drops all the keys.+-- * 'preserveMissing' leaves all the entries alone.+-- * 'mapMaybeMissing' does not use the 'Applicative' context.+--+-- When 'mergeA' is given three arguments, it is inlined at the call+-- site. To prevent excessive inlining, you should generally only use+-- 'mergeA' to define custom combining functions.+--+-- @since 0.5.9+mergeA+  :: (Applicative f)+  => WhenMissing f a c -- ^ What to do with keys in @m1@ but not @m2@+  -> WhenMissing f b c -- ^ What to do with keys in @m2@ but not @m1@+  -> WhenMatched f a b c -- ^ What to do with keys in both @m1@ and @m2@+  -> Word64Map a -- ^ Map @m1@+  -> Word64Map b -- ^ Map @m2@+  -> f (Word64Map c)+mergeA+    WhenMissing{missingSubtree = g1t, missingKey = g1k}+    WhenMissing{missingSubtree = g2t, missingKey = g2k}+    WhenMatched{matchedKey = f}+    = go+  where+    go t1  Nil = g1t t1+    go Nil t2  = g2t t2++    -- This case is already covered below.+    -- go (Tip k1 x1) (Tip k2 x2) = mergeTips k1 x1 k2 x2++    go (Tip k1 x1) t2' = merge2 t2'+      where+        merge2 t2@(Bin p2 m2 l2 r2)+          | nomatch k1 p2 m2 = linkA k1 (subsingletonBy g1k k1 x1) p2 (g2t t2)+          | zero k1 m2       = binA p2 m2 (merge2 l2) (g2t r2)+          | otherwise        = binA p2 m2 (g2t l2) (merge2 r2)+        merge2 (Tip k2 x2)   = mergeTips k1 x1 k2 x2+        merge2 Nil           = subsingletonBy g1k k1 x1++    go t1' (Tip k2 x2) = merge1 t1'+      where+        merge1 t1@(Bin p1 m1 l1 r1)+          | nomatch k2 p1 m1 = linkA p1 (g1t t1) k2 (subsingletonBy g2k k2 x2)+          | zero k2 m1       = binA p1 m1 (merge1 l1) (g1t r1)+          | otherwise        = binA p1 m1 (g1t l1) (merge1 r1)+        merge1 (Tip k1 x1)   = mergeTips k1 x1 k2 x2+        merge1 Nil           = subsingletonBy g2k k2 x2++    go t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)+      | shorter m1 m2  = merge1+      | shorter m2 m1  = merge2+      | p1 == p2       = binA p1 m1 (go l1 l2) (go r1 r2)+      | otherwise      = linkA p1 (g1t t1) p2 (g2t t2)+      where+        merge1 | nomatch p2 p1 m1  = linkA p1 (g1t t1) p2 (g2t t2)+               | zero p2 m1        = binA p1 m1 (go  l1 t2) (g1t r1)+               | otherwise         = binA p1 m1 (g1t l1)    (go  r1 t2)+        merge2 | nomatch p1 p2 m2  = linkA p1 (g1t t1) p2 (g2t t2)+               | zero p1 m2        = binA p2 m2 (go  t1 l2) (g2t    r2)+               | otherwise         = binA p2 m2 (g2t    l2) (go  t1 r2)++    subsingletonBy gk k x = maybe Nil (Tip k) <$> gk k x+    {-# INLINE subsingletonBy #-}++    mergeTips k1 x1 k2 x2+      | k1 == k2  = maybe Nil (Tip k1) <$> f k1 x1 x2+      | k1 <  k2  = liftA2 (subdoubleton k1 k2) (g1k k1 x1) (g2k k2 x2)+        {-+        = link_ k1 k2 <$> subsingletonBy g1k k1 x1 <*> subsingletonBy g2k k2 x2+        -}+      | otherwise = liftA2 (subdoubleton k2 k1) (g2k k2 x2) (g1k k1 x1)+    {-# INLINE mergeTips #-}++    subdoubleton _ _   Nothing Nothing     = Nil+    subdoubleton _ k2  Nothing (Just y2)   = Tip k2 y2+    subdoubleton k1 _  (Just y1) Nothing   = Tip k1 y1+    subdoubleton k1 k2 (Just y1) (Just y2) = link k1 (Tip k1 y1) k2 (Tip k2 y2)+    {-# INLINE subdoubleton #-}++    -- A variant of 'link_' which makes sure to execute side-effects+    -- in the right order.+    linkA+        :: Applicative f+        => Prefix -> f (Word64Map a)+        -> Prefix -> f (Word64Map a)+        -> f (Word64Map a)+    linkA p1 t1 p2 t2+      | zero p1 m = binA p m t1 t2+      | otherwise = binA p m t2 t1+      where+        m = branchMask p1 p2+        p = mask p1 m+    {-# INLINE linkA #-}++    -- A variant of 'bin' that ensures that effects for negative keys are executed+    -- first.+    binA+        :: Applicative f+        => Prefix+        -> Mask+        -> f (Word64Map a)+        -> f (Word64Map a)+        -> f (Word64Map a)+    binA p m a b+      | m < 0     = liftA2 (flip (bin p m)) b a+      | otherwise = liftA2       (bin p m)  a b+    {-# INLINE binA #-}+{-# INLINE mergeA #-}+++{--------------------------------------------------------------------+  Min\/Max+--------------------------------------------------------------------}++-- | \(O(\min(n,W))\). Update the value at the minimal key.+--+-- > updateMinWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]+-- > updateMinWithKey (\ _ _ -> Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"++updateMinWithKey :: (Key -> a -> Maybe a) -> Word64Map a -> Word64Map a+updateMinWithKey f t =+  case t of Bin p m l r | m < 0 -> binCheckRight p m l (go f r)+            _ -> go f t+  where+    go f' (Bin p m l r) = binCheckLeft p m (go f' l) r+    go f' (Tip k y) = case f' k y of+                        Just y' -> Tip k y'+                        Nothing -> Nil+    go _ Nil = error "updateMinWithKey Nil"++-- | \(O(\min(n,W))\). Update the value at the maximal key.+--+-- > updateMaxWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]+-- > updateMaxWithKey (\ _ _ -> Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"++updateMaxWithKey :: (Key -> a -> Maybe a) -> Word64Map a -> Word64Map a+updateMaxWithKey f t =+  case t of Bin p m l r | m < 0 -> binCheckLeft p m (go f l) r+            _ -> go f t+  where+    go f' (Bin p m l r) = binCheckRight p m l (go f' r)+    go f' (Tip k y) = case f' k y of+                        Just y' -> Tip k y'+                        Nothing -> Nil+    go _ Nil = error "updateMaxWithKey Nil"+++data View a = View {-# UNPACK #-} !Key a !(Word64Map a)++-- | \(O(\min(n,W))\). Retrieves the maximal (key,value) pair of the map, and+-- the map stripped of that element, or 'Nothing' if passed an empty map.+--+-- > maxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")+-- > maxViewWithKey empty == Nothing++maxViewWithKey :: Word64Map a -> Maybe ((Key, a), Word64Map a)+maxViewWithKey t = case t of+  Nil -> Nothing+  _ -> Just $ case maxViewWithKeySure t of+                View k v t' -> ((k, v), t')+{-# INLINE maxViewWithKey #-}++maxViewWithKeySure :: Word64Map a -> View a+maxViewWithKeySure t =+  case t of+    Nil -> error "maxViewWithKeySure Nil"+    Bin p m l r | m < 0 ->+      case go l of View k a l' -> View k a (binCheckLeft p m l' r)+    _ -> go t+  where+    go (Bin p m l r) =+        case go r of View k a r' -> View k a (binCheckRight p m l r')+    go (Tip k y) = View k y Nil+    go Nil = error "maxViewWithKey_go Nil"+-- See note on NOINLINE at minViewWithKeySure+{-# NOINLINE maxViewWithKeySure #-}++-- | \(O(\min(n,W))\). Retrieves the minimal (key,value) pair of the map, and+-- the map stripped of that element, or 'Nothing' if passed an empty map.+--+-- > minViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")+-- > minViewWithKey empty == Nothing++minViewWithKey :: Word64Map a -> Maybe ((Key, a), Word64Map a)+minViewWithKey t =+  case t of+    Nil -> Nothing+    _ -> Just $ case minViewWithKeySure t of+                  View k v t' -> ((k, v), t')+-- We inline this to give GHC the best possible chance of+-- getting rid of the Maybe, pair, and Int constructors, as+-- well as a thunk under the Just. That is, we really want to+-- be certain this inlines!+{-# INLINE minViewWithKey #-}++minViewWithKeySure :: Word64Map a -> View a+minViewWithKeySure t =+  case t of+    Nil -> error "minViewWithKeySure Nil"+    Bin p m l r | m < 0 ->+      case go r of+        View k a r' -> View k a (binCheckRight p m l r')+    _ -> go t+  where+    go (Bin p m l r) =+        case go l of View k a l' -> View k a (binCheckLeft p m l' r)+    go (Tip k y) = View k y Nil+    go Nil = error "minViewWithKey_go Nil"+-- There's never anything significant to be gained by inlining+-- this. Sufficiently recent GHC versions will inline the wrapper+-- anyway, which should be good enough.+{-# NOINLINE minViewWithKeySure #-}++-- | \(O(\min(n,W))\). Update the value at the maximal key.+--+-- > updateMax (\ a -> Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]+-- > updateMax (\ _ -> Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"++updateMax :: (a -> Maybe a) -> Word64Map a -> Word64Map a+updateMax f = updateMaxWithKey (const f)++-- | \(O(\min(n,W))\). Update the value at the minimal key.+--+-- > updateMin (\ a -> Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]+-- > updateMin (\ _ -> Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"++updateMin :: (a -> Maybe a) -> Word64Map a -> Word64Map a+updateMin f = updateMinWithKey (const f)++-- | \(O(\min(n,W))\). Retrieves the maximal key of the map, and the map+-- stripped of that element, or 'Nothing' if passed an empty map.+maxView :: Word64Map a -> Maybe (a, Word64Map a)+maxView t = fmap (\((_, x), t') -> (x, t')) (maxViewWithKey t)++-- | \(O(\min(n,W))\). Retrieves the minimal key of the map, and the map+-- stripped of that element, or 'Nothing' if passed an empty map.+minView :: Word64Map a -> Maybe (a, Word64Map a)+minView t = fmap (\((_, x), t') -> (x, t')) (minViewWithKey t)++-- | \(O(\min(n,W))\). Delete and find the maximal element.+-- This function throws an error if the map is empty. Use 'maxViewWithKey'+-- if the map may be empty.+deleteFindMax :: Word64Map a -> ((Key, a), Word64Map a)+deleteFindMax = fromMaybe (error "deleteFindMax: empty map has no maximal element") . maxViewWithKey++-- | \(O(\min(n,W))\). Delete and find the minimal element.+-- This function throws an error if the map is empty. Use 'minViewWithKey'+-- if the map may be empty.+deleteFindMin :: Word64Map a -> ((Key, a), Word64Map a)+deleteFindMin = fromMaybe (error "deleteFindMin: empty map has no minimal element") . minViewWithKey++-- | \(O(\min(n,W))\). The minimal key of the map. Returns 'Nothing' if the map is empty.+lookupMin :: Word64Map a -> Maybe (Key, a)+lookupMin Nil = Nothing+lookupMin (Tip k v) = Just (k,v)+lookupMin (Bin _ m l r)+  | m < 0     = go r+  | otherwise = go l+    where go (Tip k v)      = Just (k,v)+          go (Bin _ _ l' _) = go l'+          go Nil            = Nothing++-- | \(O(\min(n,W))\). The minimal key of the map. Calls 'error' if the map is empty.+-- Use 'minViewWithKey' if the map may be empty.+findMin :: Word64Map a -> (Key, a)+findMin t+  | Just r <- lookupMin t = r+  | otherwise = error "findMin: empty map has no minimal element"++-- | \(O(\min(n,W))\). The maximal key of the map. Returns 'Nothing' if the map is empty.+lookupMax :: Word64Map a -> Maybe (Key, a)+lookupMax Nil = Nothing+lookupMax (Tip k v) = Just (k,v)+lookupMax (Bin _ m l r)+  | m < 0     = go l+  | otherwise = go r+    where go (Tip k v)      = Just (k,v)+          go (Bin _ _ _ r') = go r'+          go Nil            = Nothing++-- | \(O(\min(n,W))\). The maximal key of the map. Calls 'error' if the map is empty.+-- Use 'maxViewWithKey' if the map may be empty.+findMax :: Word64Map a -> (Key, a)+findMax t+  | Just r <- lookupMax t = r+  | otherwise = error "findMax: empty map has no maximal element"++-- | \(O(\min(n,W))\). Delete the minimal key. Returns an empty map if the map is empty.+--+-- Note that this is a change of behaviour for consistency with 'Data.Map.Map' &#8211;+-- versions prior to 0.5 threw an error if the 'Word64Map' was already empty.+deleteMin :: Word64Map a -> Word64Map a+deleteMin = maybe Nil snd . minView++-- | \(O(\min(n,W))\). Delete the maximal key. Returns an empty map if the map is empty.+--+-- Note that this is a change of behaviour for consistency with 'Data.Map.Map' &#8211;+-- versions prior to 0.5 threw an error if the 'Word64Map' was already empty.+deleteMax :: Word64Map a -> Word64Map a+deleteMax = maybe Nil snd . maxView+++{--------------------------------------------------------------------+  Submap+--------------------------------------------------------------------}+-- | \(O(n+m)\). Is this a proper submap? (ie. a submap but not equal).+-- Defined as (@'isProperSubmapOf' = 'isProperSubmapOfBy' (==)@).+isProperSubmapOf :: Eq a => Word64Map a -> Word64Map a -> Bool+isProperSubmapOf m1 m2+  = isProperSubmapOfBy (==) m1 m2++{- | \(O(n+m)\). Is this a proper submap? (ie. a submap but not equal).+ The expression (@'isProperSubmapOfBy' f m1 m2@) returns 'True' when+ @keys m1@ and @keys m2@ are not equal,+ all keys in @m1@ are in @m2@, and when @f@ returns 'True' when+ applied to their respective values. For example, the following+ expressions are all 'True':++  > isProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])+  > isProperSubmapOfBy (<=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])++ But the following are all 'False':++  > isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])+  > isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])+  > isProperSubmapOfBy (<)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])+-}+isProperSubmapOfBy :: (a -> b -> Bool) -> Word64Map a -> Word64Map b -> Bool+isProperSubmapOfBy predicate t1 t2+  = case submapCmp predicate t1 t2 of+      LT -> True+      _  -> False++submapCmp :: (a -> b -> Bool) -> Word64Map a -> Word64Map b -> Ordering+submapCmp predicate t1@(Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)+  | shorter m1 m2  = GT+  | shorter m2 m1  = submapCmpLt+  | p1 == p2       = submapCmpEq+  | otherwise      = GT  -- disjoint+  where+    submapCmpLt | nomatch p1 p2 m2  = GT+                | zero p1 m2        = submapCmp predicate t1 l2+                | otherwise         = submapCmp predicate t1 r2+    submapCmpEq = case (submapCmp predicate l1 l2, submapCmp predicate r1 r2) of+                    (GT,_ ) -> GT+                    (_ ,GT) -> GT+                    (EQ,EQ) -> EQ+                    _       -> LT++submapCmp _         (Bin _ _ _ _) _  = GT+submapCmp predicate (Tip kx x) (Tip ky y)+  | (kx == ky) && predicate x y = EQ+  | otherwise                   = GT  -- disjoint+submapCmp predicate (Tip k x) t+  = case lookup k t of+     Just y | predicate x y -> LT+     _                      -> GT -- disjoint+submapCmp _    Nil Nil = EQ+submapCmp _    Nil _   = LT++-- | \(O(n+m)\). Is this a submap?+-- Defined as (@'isSubmapOf' = 'isSubmapOfBy' (==)@).+isSubmapOf :: Eq a => Word64Map a -> Word64Map a -> Bool+isSubmapOf m1 m2+  = isSubmapOfBy (==) m1 m2++{- | \(O(n+m)\).+ The expression (@'isSubmapOfBy' f m1 m2@) returns 'True' if+ all keys in @m1@ are in @m2@, and when @f@ returns 'True' when+ applied to their respective values. For example, the following+ expressions are all 'True':++  > isSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])+  > isSubmapOfBy (<=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])+  > isSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])++ But the following are all 'False':++  > isSubmapOfBy (==) (fromList [(1,2)]) (fromList [(1,1),(2,2)])+  > isSubmapOfBy (<) (fromList [(1,1)]) (fromList [(1,1),(2,2)])+  > isSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])+-}+isSubmapOfBy :: (a -> b -> Bool) -> Word64Map a -> Word64Map b -> Bool+isSubmapOfBy predicate t1@(Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)+  | shorter m1 m2  = False+  | shorter m2 m1  = match p1 p2 m2 &&+                       if zero p1 m2+                       then isSubmapOfBy predicate t1 l2+                       else isSubmapOfBy predicate t1 r2+  | otherwise      = (p1==p2) && isSubmapOfBy predicate l1 l2 && isSubmapOfBy predicate r1 r2+isSubmapOfBy _         (Bin _ _ _ _) _ = False+isSubmapOfBy predicate (Tip k x) t     = case lookup k t of+                                         Just y  -> predicate x y+                                         Nothing -> False+isSubmapOfBy _         Nil _           = True++{--------------------------------------------------------------------+  Mapping+--------------------------------------------------------------------}+-- | \(O(n)\). Map a function over all values in the map.+--+-- > map (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]++map :: (a -> b) -> Word64Map a -> Word64Map b+map f = go+  where+    go (Bin p m l r) = Bin p m (go l) (go r)+    go (Tip k x)     = Tip k (f x)+    go Nil           = Nil++#ifdef __GLASGOW_HASKELL__+{-# NOINLINE [1] map #-}+{-# RULES+"map/map" forall f g xs . map f (map g xs) = map (f . g) xs+"map/coerce" map coerce = coerce+ #-}+#endif++-- | \(O(n)\). Map a function over all values in the map.+--+-- > let f key x = (show key) ++ ":" ++ x+-- > mapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]++mapWithKey :: (Key -> a -> b) -> Word64Map a -> Word64Map b+mapWithKey f t+  = case t of+      Bin p m l r -> Bin p m (mapWithKey f l) (mapWithKey f r)+      Tip k x     -> Tip k (f k x)+      Nil         -> Nil++#ifdef __GLASGOW_HASKELL__+{-# NOINLINE [1] mapWithKey #-}+{-# RULES+"mapWithKey/mapWithKey" forall f g xs . mapWithKey f (mapWithKey g xs) =+  mapWithKey (\k a -> f k (g k a)) xs+"mapWithKey/map" forall f g xs . mapWithKey f (map g xs) =+  mapWithKey (\k a -> f k (g a)) xs+"map/mapWithKey" forall f g xs . map f (mapWithKey g xs) =+  mapWithKey (\k a -> f (g k a)) xs+ #-}+#endif++-- | \(O(n)\).+-- @'traverseWithKey' f s == 'fromList' <$> 'traverse' (\(k, v) -> (,) k <$> f k v) ('toList' m)@+-- That is, behaves exactly like a regular 'traverse' except that the traversing+-- function also has access to the key associated with a value.+--+-- > traverseWithKey (\k v -> if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])+-- > traverseWithKey (\k v -> if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing+traverseWithKey :: Applicative t => (Key -> a -> t b) -> Word64Map a -> t (Word64Map b)+traverseWithKey f = go+  where+    go Nil = pure Nil+    go (Tip k v) = Tip k <$> f k v+    go (Bin p m l r)+      | m < 0     = liftA2 (flip (Bin p m)) (go r) (go l)+      | otherwise = liftA2 (Bin p m) (go l) (go r)+{-# INLINE traverseWithKey #-}++-- | \(O(n)\). The function @'mapAccum'@ threads an accumulating+-- argument through the map in ascending order of keys.+--+-- > let f a b = (a ++ b, b ++ "X")+-- > mapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])++mapAccum :: (a -> b -> (a,c)) -> a -> Word64Map b -> (a,Word64Map c)+mapAccum f = mapAccumWithKey (\a' _ x -> f a' x)++-- | \(O(n)\). The function @'mapAccumWithKey'@ threads an accumulating+-- argument through the map in ascending order of keys.+--+-- > let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")+-- > mapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])++mapAccumWithKey :: (a -> Key -> b -> (a,c)) -> a -> Word64Map b -> (a,Word64Map c)+mapAccumWithKey f a t+  = mapAccumL f a t++-- | \(O(n)\). The function @'mapAccumL'@ threads an accumulating+-- argument through the map in ascending order of keys.+mapAccumL :: (a -> Key -> b -> (a,c)) -> a -> Word64Map b -> (a,Word64Map c)+mapAccumL f a t+  = case t of+      Bin p m l r+        | m < 0 ->+            let (a1,r') = mapAccumL f a r+                (a2,l') = mapAccumL f a1 l+            in (a2,Bin p m l' r')+        | otherwise  ->+            let (a1,l') = mapAccumL f a l+                (a2,r') = mapAccumL f a1 r+            in (a2,Bin p m l' r')+      Tip k x     -> let (a',x') = f a k x in (a',Tip k x')+      Nil         -> (a,Nil)++-- | \(O(n)\). The function @'mapAccumRWithKey'@ threads an accumulating+-- argument through the map in descending order of keys.+mapAccumRWithKey :: (a -> Key -> b -> (a,c)) -> a -> Word64Map b -> (a,Word64Map c)+mapAccumRWithKey f a t+  = case t of+      Bin p m l r+        | m < 0 ->+            let (a1,l') = mapAccumRWithKey f a l+                (a2,r') = mapAccumRWithKey f a1 r+            in (a2,Bin p m l' r')+        | otherwise  ->+            let (a1,r') = mapAccumRWithKey f a r+                (a2,l') = mapAccumRWithKey f a1 l+            in (a2,Bin p m l' r')+      Tip k x     -> let (a',x') = f a k x in (a',Tip k x')+      Nil         -> (a,Nil)++-- | \(O(n \min(n,W))\).+-- @'mapKeys' f s@ is the map obtained by applying @f@ to each key of @s@.+--+-- The size of the result may be smaller if @f@ maps two or more distinct+-- keys to the same new key.  In this case the value at the greatest of the+-- original keys is retained.+--+-- > mapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]+-- > mapKeys (\ _ -> 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"+-- > mapKeys (\ _ -> 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"++mapKeys :: (Key->Key) -> Word64Map a -> Word64Map a+mapKeys f = fromList . foldrWithKey (\k x xs -> (f k, x) : xs) []++-- | \(O(n \min(n,W))\).+-- @'mapKeysWith' c f s@ is the map obtained by applying @f@ to each key of @s@.+--+-- The size of the result may be smaller if @f@ maps two or more distinct+-- keys to the same new key.  In this case the associated values will be+-- combined using @c@.+--+-- > mapKeysWith (++) (\ _ -> 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"+-- > mapKeysWith (++) (\ _ -> 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"++mapKeysWith :: (a -> a -> a) -> (Key->Key) -> Word64Map a -> Word64Map a+mapKeysWith c f+  = fromListWith c . foldrWithKey (\k x xs -> (f k, x) : xs) []++-- | \(O(n \min(n,W))\).+-- @'mapKeysMonotonic' f s == 'mapKeys' f s@, but works only when @f@+-- is strictly monotonic.+-- That is, for any values @x@ and @y@, if @x@ < @y@ then @f x@ < @f y@.+-- /The precondition is not checked./+-- Semi-formally, we have:+--+-- > and [x < y ==> f x < f y | x <- ls, y <- ls]+-- >                     ==> mapKeysMonotonic f s == mapKeys f s+-- >     where ls = keys s+--+-- This means that @f@ maps distinct original keys to distinct resulting keys.+-- This function has slightly better performance than 'mapKeys'.+--+-- > mapKeysMonotonic (\ k -> k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]++mapKeysMonotonic :: (Key->Key) -> Word64Map a -> Word64Map a+mapKeysMonotonic f+  = fromDistinctAscList . foldrWithKey (\k x xs -> (f k, x) : xs) []++{--------------------------------------------------------------------+  Filter+--------------------------------------------------------------------}+-- | \(O(n)\). Filter all values that satisfy some predicate.+--+-- > filter (> "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"+-- > filter (> "x") (fromList [(5,"a"), (3,"b")]) == empty+-- > filter (< "a") (fromList [(5,"a"), (3,"b")]) == empty++filter :: (a -> Bool) -> Word64Map a -> Word64Map a+filter p m+  = filterWithKey (\_ x -> p x) m++-- | \(O(n)\). Filter all keys\/values that satisfy some predicate.+--+-- > filterWithKey (\k _ -> k > 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"++filterWithKey :: (Key -> a -> Bool) -> Word64Map a -> Word64Map a+filterWithKey predicate = go+    where+    go Nil           = Nil+    go t@(Tip k x)   = if predicate k x then t else Nil+    go (Bin p m l r) = bin p m (go l) (go r)++-- | \(O(n)\). Partition the map according to some predicate. The first+-- map contains all elements that satisfy the predicate, the second all+-- elements that fail the predicate. See also 'split'.+--+-- > partition (> "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")+-- > partition (< "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)+-- > partition (> "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])++partition :: (a -> Bool) -> Word64Map a -> (Word64Map a,Word64Map a)+partition p m+  = partitionWithKey (\_ x -> p x) m++-- | \(O(n)\). Partition the map according to some predicate. The first+-- map contains all elements that satisfy the predicate, the second all+-- elements that fail the predicate. See also 'split'.+--+-- > partitionWithKey (\ k _ -> k > 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")+-- > partitionWithKey (\ k _ -> k < 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)+-- > partitionWithKey (\ k _ -> k > 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])++partitionWithKey :: (Key -> a -> Bool) -> Word64Map a -> (Word64Map a,Word64Map a)+partitionWithKey predicate0 t0 = toPair $ go predicate0 t0+  where+    go predicate t =+      case t of+        Bin p m l r ->+          let (l1 :*: l2) = go predicate l+              (r1 :*: r2) = go predicate r+          in bin p m l1 r1 :*: bin p m l2 r2+        Tip k x+          | predicate k x -> (t :*: Nil)+          | otherwise     -> (Nil :*: t)+        Nil -> (Nil :*: Nil)++-- | \(O(\min(n,W))\). Take while a predicate on the keys holds.+-- The user is responsible for ensuring that for all @Int@s, @j \< k ==\> p j \>= p k@.+-- See note at 'spanAntitone'.+--+-- @+-- takeWhileAntitone p = 'fromDistinctAscList' . 'Data.List.takeWhile' (p . fst) . 'toList'+-- takeWhileAntitone p = 'filterWithKey' (\\k _ -> p k)+-- @+--+-- @since 0.6.7+takeWhileAntitone :: (Key -> Bool) -> Word64Map a -> Word64Map a+takeWhileAntitone predicate t =+  case t of+    Bin p m l r+      | m < 0 ->+        if predicate 0 -- handle negative numbers.+        then bin p m (go predicate l) r+        else go predicate r+    _ -> go predicate t+  where+    go predicate' (Bin p m l r)+      | predicate' $! p+m = bin p m l (go predicate' r)+      | otherwise         = go predicate' l+    go predicate' t'@(Tip ky _)+      | predicate' ky = t'+      | otherwise     = Nil+    go _ Nil = Nil++-- | \(O(\min(n,W))\). Drop while a predicate on the keys holds.+-- The user is responsible for ensuring that for all @Int@s, @j \< k ==\> p j \>= p k@.+-- See note at 'spanAntitone'.+--+-- @+-- dropWhileAntitone p = 'fromDistinctAscList' . 'Data.List.dropWhile' (p . fst) . 'toList'+-- dropWhileAntitone p = 'filterWithKey' (\\k _ -> not (p k))+-- @+--+-- @since 0.6.7+dropWhileAntitone :: (Key -> Bool) -> Word64Map a -> Word64Map a+dropWhileAntitone predicate t =+  case t of+    Bin p m l r+      | m < 0 ->+        if predicate 0 -- handle negative numbers.+        then go predicate l+        else bin p m l (go predicate r)+    _ -> go predicate t+  where+    go predicate' (Bin p m l r)+      | predicate' $! p+m = go predicate' r+      | otherwise         = bin p m (go predicate' l) r+    go predicate' t'@(Tip ky _)+      | predicate' ky = Nil+      | otherwise     = t'+    go _ Nil = Nil++-- | \(O(\min(n,W))\). Divide a map at the point where a predicate on the keys stops holding.+-- The user is responsible for ensuring that for all @Int@s, @j \< k ==\> p j \>= p k@.+--+-- @+-- spanAntitone p xs = ('takeWhileAntitone' p xs, 'dropWhileAntitone' p xs)+-- spanAntitone p xs = 'partitionWithKey' (\\k _ -> p k) xs+-- @+--+-- Note: if @p@ is not actually antitone, then @spanAntitone@ will split the map+-- at some /unspecified/ point.+--+-- @since 0.6.7+spanAntitone :: (Key -> Bool) -> Word64Map a -> (Word64Map a, Word64Map a)+spanAntitone predicate t =+  case t of+    Bin p m l r+      | m < 0 ->+        if predicate 0 -- handle negative numbers.+        then+          case go predicate l of+            (lt :*: gt) ->+              let !lt' = bin p m lt r+              in (lt', gt)+        else+          case go predicate r of+            (lt :*: gt) ->+              let !gt' = bin p m l gt+              in (lt, gt')+    _ -> case go predicate t of+          (lt :*: gt) -> (lt, gt)+  where+    go predicate' (Bin p m l r)+      | predicate' $! p+m = case go predicate' r of (lt :*: gt) -> bin p m l lt :*: gt+      | otherwise         = case go predicate' l of (lt :*: gt) -> lt :*: bin p m gt r+    go predicate' t'@(Tip ky _)+      | predicate' ky = (t' :*: Nil)+      | otherwise     = (Nil :*: t')+    go _ Nil = (Nil :*: Nil)++-- | \(O(n)\). Map values and collect the 'Just' results.+--+-- > let f x = if x == "a" then Just "new a" else Nothing+-- > mapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"++mapMaybe :: (a -> Maybe b) -> Word64Map a -> Word64Map b+mapMaybe f = mapMaybeWithKey (\_ x -> f x)++-- | \(O(n)\). Map keys\/values and collect the 'Just' results.+--+-- > let f k _ = if k < 5 then Just ("key : " ++ (show k)) else Nothing+-- > mapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"++mapMaybeWithKey :: (Key -> a -> Maybe b) -> Word64Map a -> Word64Map b+mapMaybeWithKey f (Bin p m l r)+  = bin p m (mapMaybeWithKey f l) (mapMaybeWithKey f r)+mapMaybeWithKey f (Tip k x) = case f k x of+  Just y  -> Tip k y+  Nothing -> Nil+mapMaybeWithKey _ Nil = Nil++-- | \(O(n)\). Map values and separate the 'Left' and 'Right' results.+--+-- > let f a = if a < "c" then Left a else Right a+-- > mapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])+-- >     == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])+-- >+-- > mapEither (\ a -> Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])+-- >     == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])++mapEither :: (a -> Either b c) -> Word64Map a -> (Word64Map b, Word64Map c)+mapEither f m+  = mapEitherWithKey (\_ x -> f x) m++-- | \(O(n)\). Map keys\/values and separate the 'Left' and 'Right' results.+--+-- > let f k a = if k < 5 then Left (k * 2) else Right (a ++ a)+-- > mapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])+-- >     == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])+-- >+-- > mapEitherWithKey (\_ a -> Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])+-- >     == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])++mapEitherWithKey :: (Key -> a -> Either b c) -> Word64Map a -> (Word64Map b, Word64Map c)+mapEitherWithKey f0 t0 = toPair $ go f0 t0+  where+    go f (Bin p m l r) =+      bin p m l1 r1 :*: bin p m l2 r2+      where+        (l1 :*: l2) = go f l+        (r1 :*: r2) = go f r+    go f (Tip k x) = case f k x of+      Left y  -> (Tip k y :*: Nil)+      Right z -> (Nil :*: Tip k z)+    go _ Nil = (Nil :*: Nil)++-- | \(O(\min(n,W))\). The expression (@'split' k map@) is a pair @(map1,map2)@+-- where all keys in @map1@ are lower than @k@ and all keys in+-- @map2@ larger than @k@. Any key equal to @k@ is found in neither @map1@ nor @map2@.+--+-- > split 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])+-- > split 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")+-- > split 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")+-- > split 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)+-- > split 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)++split :: Key -> Word64Map a -> (Word64Map a, Word64Map a)+split k t =+  case t of+    Bin p m l r+      | m < 0 ->+        if k >= 0 -- handle negative numbers.+        then+          case go k l of+            (lt :*: gt) ->+              let !lt' = bin p m lt r+              in (lt', gt)+        else+          case go k r of+            (lt :*: gt) ->+              let !gt' = bin p m l gt+              in (lt, gt')+    _ -> case go k t of+          (lt :*: gt) -> (lt, gt)+  where+    go k' t'@(Bin p m l r)+      | nomatch k' p m = if k' > p then t' :*: Nil else Nil :*: t'+      | zero k' m = case go k' l of (lt :*: gt) -> lt :*: bin p m gt r+      | otherwise = case go k' r of (lt :*: gt) -> bin p m l lt :*: gt+    go k' t'@(Tip ky _)+      | k' > ky   = (t' :*: Nil)+      | k' < ky   = (Nil :*: t')+      | otherwise = (Nil :*: Nil)+    go _ Nil = (Nil :*: Nil)+++data SplitLookup a = SplitLookup !(Word64Map a) !(Maybe a) !(Word64Map a)++mapLT :: (Word64Map a -> Word64Map a) -> SplitLookup a -> SplitLookup a+mapLT f (SplitLookup lt fnd gt) = SplitLookup (f lt) fnd gt+{-# INLINE mapLT #-}++mapGT :: (Word64Map a -> Word64Map a) -> SplitLookup a -> SplitLookup a+mapGT f (SplitLookup lt fnd gt) = SplitLookup lt fnd (f gt)+{-# INLINE mapGT #-}++-- | \(O(\min(n,W))\). Performs a 'split' but also returns whether the pivot+-- key was found in the original map.+--+-- > splitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])+-- > splitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")+-- > splitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")+-- > splitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)+-- > splitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)++splitLookup :: Key -> Word64Map a -> (Word64Map a, Maybe a, Word64Map a)+splitLookup k t =+  case+    case t of+      Bin p m l r+        | m < 0 ->+          if k >= 0 -- handle negative numbers.+          then mapLT (flip (bin p m) r) (go k l)+          else mapGT (bin p m l) (go k r)+      _ -> go k t+  of SplitLookup lt fnd gt -> (lt, fnd, gt)+  where+    go k' t'@(Bin p m l r)+      | nomatch k' p m =+          if k' > p+          then SplitLookup t' Nothing Nil+          else SplitLookup Nil Nothing t'+      | zero k' m = mapGT (flip (bin p m) r) (go k' l)+      | otherwise = mapLT (bin p m l) (go k' r)+    go k' t'@(Tip ky y)+      | k' > ky   = SplitLookup t'  Nothing  Nil+      | k' < ky   = SplitLookup Nil Nothing  t'+      | otherwise = SplitLookup Nil (Just y) Nil+    go _ Nil      = SplitLookup Nil Nothing  Nil++{--------------------------------------------------------------------+  Fold+--------------------------------------------------------------------}+-- | \(O(n)\). Fold the values in the map using the given right-associative+-- binary operator, such that @'foldr' f z == 'Prelude.foldr' f z . 'elems'@.+--+-- For example,+--+-- > elems map = foldr (:) [] map+--+-- > let f a len = len + (length a)+-- > foldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4+foldr :: (a -> b -> b) -> b -> Word64Map a -> b+foldr f z = \t ->      -- Use lambda t to be inlinable with two arguments only.+  case t of+    Bin _ m l r+      | m < 0 -> go (go z l) r -- put negative numbers before+      | otherwise -> go (go z r) l+    _ -> go z t+  where+    go z' Nil           = z'+    go z' (Tip _ x)     = f x z'+    go z' (Bin _ _ l r) = go (go z' r) l+{-# INLINE foldr #-}++-- | \(O(n)\). A strict version of 'foldr'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldr' :: (a -> b -> b) -> b -> Word64Map a -> b+foldr' f z = \t ->      -- Use lambda t to be inlinable with two arguments only.+  case t of+    Bin _ m l r+      | m < 0 -> go (go z l) r -- put negative numbers before+      | otherwise -> go (go z r) l+    _ -> go z t+  where+    go !z' Nil          = z'+    go z' (Tip _ x)     = f x z'+    go z' (Bin _ _ l r) = go (go z' r) l+{-# INLINE foldr' #-}++-- | \(O(n)\). Fold the values in the map using the given left-associative+-- binary operator, such that @'foldl' f z == 'Prelude.foldl' f z . 'elems'@.+--+-- For example,+--+-- > elems = reverse . foldl (flip (:)) []+--+-- > let f len a = len + (length a)+-- > foldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4+foldl :: (a -> b -> a) -> a -> Word64Map b -> a+foldl f z = \t ->      -- Use lambda t to be inlinable with two arguments only.+  case t of+    Bin _ m l r+      | m < 0 -> go (go z r) l -- put negative numbers before+      | otherwise -> go (go z l) r+    _ -> go z t+  where+    go z' Nil           = z'+    go z' (Tip _ x)     = f z' x+    go z' (Bin _ _ l r) = go (go z' l) r+{-# INLINE foldl #-}++-- | \(O(n)\). A strict version of 'foldl'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldl' :: (a -> b -> a) -> a -> Word64Map b -> a+foldl' f z = \t ->      -- Use lambda t to be inlinable with two arguments only.+  case t of+    Bin _ m l r+      | m < 0 -> go (go z r) l -- put negative numbers before+      | otherwise -> go (go z l) r+    _ -> go z t+  where+    go !z' Nil          = z'+    go z' (Tip _ x)     = f z' x+    go z' (Bin _ _ l r) = go (go z' l) r+{-# INLINE foldl' #-}++-- | \(O(n)\). Fold the keys and values in the map using the given right-associative+-- binary operator, such that+-- @'foldrWithKey' f z == 'Prelude.foldr' ('uncurry' f) z . 'toAscList'@.+--+-- For example,+--+-- > keys map = foldrWithKey (\k x ks -> k:ks) [] map+--+-- > let f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"+-- > foldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"+foldrWithKey :: (Key -> a -> b -> b) -> b -> Word64Map a -> b+foldrWithKey f z = \t ->      -- Use lambda t to be inlinable with two arguments only.+  case t of+    Bin _ m l r+      | m < 0 -> go (go z l) r -- put negative numbers before+      | otherwise -> go (go z r) l+    _ -> go z t+  where+    go z' Nil           = z'+    go z' (Tip kx x)    = f kx x z'+    go z' (Bin _ _ l r) = go (go z' r) l+{-# INLINE foldrWithKey #-}++-- | \(O(n)\). A strict version of 'foldrWithKey'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldrWithKey' :: (Key -> a -> b -> b) -> b -> Word64Map a -> b+foldrWithKey' f z = \t ->      -- Use lambda t to be inlinable with two arguments only.+  case t of+    Bin _ m l r+      | m < 0 -> go (go z l) r -- put negative numbers before+      | otherwise -> go (go z r) l+    _ -> go z t+  where+    go !z' Nil          = z'+    go z' (Tip kx x)    = f kx x z'+    go z' (Bin _ _ l r) = go (go z' r) l+{-# INLINE foldrWithKey' #-}++-- | \(O(n)\). Fold the keys and values in the map using the given left-associative+-- binary operator, such that+-- @'foldlWithKey' f z == 'Prelude.foldl' (\\z' (kx, x) -> f z' kx x) z . 'toAscList'@.+--+-- For example,+--+-- > keys = reverse . foldlWithKey (\ks k x -> k:ks) []+--+-- > let f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"+-- > foldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"+foldlWithKey :: (a -> Key -> b -> a) -> a -> Word64Map b -> a+foldlWithKey f z = \t ->      -- Use lambda t to be inlinable with two arguments only.+  case t of+    Bin _ m l r+      | m < 0 -> go (go z r) l -- put negative numbers before+      | otherwise -> go (go z l) r+    _ -> go z t+  where+    go z' Nil           = z'+    go z' (Tip kx x)    = f z' kx x+    go z' (Bin _ _ l r) = go (go z' l) r+{-# INLINE foldlWithKey #-}++-- | \(O(n)\). A strict version of 'foldlWithKey'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldlWithKey' :: (a -> Key -> b -> a) -> a -> Word64Map b -> a+foldlWithKey' f z = \t ->      -- Use lambda t to be inlinable with two arguments only.+  case t of+    Bin _ m l r+      | m < 0 -> go (go z r) l -- put negative numbers before+      | otherwise -> go (go z l) r+    _ -> go z t+  where+    go !z' Nil          = z'+    go z' (Tip kx x)    = f z' kx x+    go z' (Bin _ _ l r) = go (go z' l) r+{-# INLINE foldlWithKey' #-}++-- | \(O(n)\). Fold the keys and values in the map using the given monoid, such that+--+-- @'foldMapWithKey' f = 'Prelude.fold' . 'mapWithKey' f@+--+-- This can be an asymptotically faster than 'foldrWithKey' or 'foldlWithKey' for some monoids.+--+-- @since 0.5.4+foldMapWithKey :: Monoid m => (Key -> a -> m) -> Word64Map a -> m+foldMapWithKey f = go+  where+    go Nil           = mempty+    go (Tip kx x)    = f kx x+    go (Bin _ m l r)+      | m < 0     = go r `mappend` go l+      | otherwise = go l `mappend` go r+{-# INLINE foldMapWithKey #-}++{--------------------------------------------------------------------+  List variations+--------------------------------------------------------------------}+-- | \(O(n)\).+-- Return all elements of the map in the ascending order of their keys.+-- Subject to list fusion.+--+-- > elems (fromList [(5,"a"), (3,"b")]) == ["b","a"]+-- > elems empty == []++elems :: Word64Map a -> [a]+elems = foldr (:) []++-- | \(O(n)\). Return all keys of the map in ascending order. Subject to list+-- fusion.+--+-- > keys (fromList [(5,"a"), (3,"b")]) == [3,5]+-- > keys empty == []++keys  :: Word64Map a -> [Key]+keys = foldrWithKey (\k _ ks -> k : ks) []++-- | \(O(n)\). An alias for 'toAscList'. Returns all key\/value pairs in the+-- map in ascending key order. Subject to list fusion.+--+-- > assocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]+-- > assocs empty == []++assocs :: Word64Map a -> [(Key,a)]+assocs = toAscList++-- | \(O(n \min(n,W))\). The set of all keys of the map.+--+-- > keysSet (fromList [(5,"a"), (3,"b")]) == Data.Word64Set.fromList [3,5]+-- > keysSet empty == Data.Word64Set.empty++keysSet :: Word64Map a -> Word64Set.Word64Set+keysSet Nil = Word64Set.Nil+keysSet (Tip kx _) = Word64Set.singleton kx+keysSet (Bin p m l r)+  | m .&. Word64Set.suffixBitMask == 0 = Word64Set.Bin p m (keysSet l) (keysSet r)+  | otherwise = Word64Set.Tip (p .&. Word64Set.prefixBitMask) (computeBm (computeBm 0 l) r)+  where computeBm !acc (Bin _ _ l' r') = computeBm (computeBm acc l') r'+        computeBm acc (Tip kx _) = acc .|. Word64Set.bitmapOf kx+        computeBm _   Nil = error "Data.Word64Set.keysSet: Nil"++-- | \(O(n)\). Build a map from a set of keys and a function which for each key+-- computes its value.+--+-- > fromSet (\k -> replicate k 'a') (Data.Word64Set.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]+-- > fromSet undefined Data.Word64Set.empty == empty++fromSet :: (Key -> a) -> Word64Set.Word64Set -> Word64Map a+fromSet _ Word64Set.Nil = Nil+fromSet f (Word64Set.Bin p m l r) = Bin p m (fromSet f l) (fromSet f r)+fromSet f (Word64Set.Tip kx bm) = buildTree f kx bm (Word64Set.suffixBitMask + 1)+  where+    -- This is slightly complicated, as we to convert the dense+    -- representation of Word64Set into tree representation of Word64Map.+    --+    -- We are given a nonzero bit mask 'bmask' of 'bits' bits with+    -- prefix 'prefix'. We split bmask into halves corresponding+    -- to left and right subtree. If they are both nonempty, we+    -- create a Bin node, otherwise exactly one of them is nonempty+    -- and we construct the Word64Map from that half.+    buildTree g !prefix !bmask bits = case bits of+      0 -> Tip prefix (g prefix)+      _ -> case intFromNat ((natFromInt bits) `shiftRL` 1) of+        bits2+          | bmask .&. ((1 `shiftLL` fromIntegral bits2) - 1) == 0 ->+              buildTree g (prefix + bits2) (bmask `shiftRL` fromIntegral bits2) bits2+          | (bmask `shiftRL` fromIntegral bits2) .&. ((1 `shiftLL` fromIntegral bits2) - 1) == 0 ->+              buildTree g prefix bmask bits2+          | otherwise ->+              Bin prefix bits2+                (buildTree g prefix bmask bits2)+                (buildTree g (prefix + bits2) (bmask `shiftRL` fromIntegral bits2) bits2)++{--------------------------------------------------------------------+  Lists+--------------------------------------------------------------------}++#ifdef __GLASGOW_HASKELL__+-- | @since 0.5.6.2+instance GHCExts.IsList (Word64Map a) where+  type Item (Word64Map a) = (Key,a)+  fromList = fromList+  toList   = toList+#endif++-- | \(O(n)\). Convert the map to a list of key\/value pairs. Subject to list+-- fusion.+--+-- > toList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]+-- > toList empty == []++toList :: Word64Map a -> [(Key,a)]+toList = toAscList++-- | \(O(n)\). Convert the map to a list of key\/value pairs where the+-- keys are in ascending order. Subject to list fusion.+--+-- > toAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]++toAscList :: Word64Map a -> [(Key,a)]+toAscList = foldrWithKey (\k x xs -> (k,x):xs) []++-- | \(O(n)\). Convert the map to a list of key\/value pairs where the keys+-- are in descending order. Subject to list fusion.+--+-- > toDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]++toDescList :: Word64Map a -> [(Key,a)]+toDescList = foldlWithKey (\xs k x -> (k,x):xs) []++-- List fusion for the list generating functions.+#if __GLASGOW_HASKELL__+-- The foldrFB and foldlFB are fold{r,l}WithKey equivalents, used for list fusion.+-- They are important to convert unfused methods back, see mapFB in prelude.+foldrFB :: (Key -> a -> b -> b) -> b -> Word64Map a -> b+foldrFB = foldrWithKey+{-# INLINE[0] foldrFB #-}+foldlFB :: (a -> Key -> b -> a) -> a -> Word64Map b -> a+foldlFB = foldlWithKey+{-# INLINE[0] foldlFB #-}++-- Inline assocs and toList, so that we need to fuse only toAscList.+{-# INLINE assocs #-}+{-# INLINE toList #-}++-- The fusion is enabled up to phase 2 included. If it does not succeed,+-- convert in phase 1 the expanded elems,keys,to{Asc,Desc}List calls back to+-- elems,keys,to{Asc,Desc}List.  In phase 0, we inline fold{lr}FB (which were+-- used in a list fusion, otherwise it would go away in phase 1), and let compiler+-- do whatever it wants with elems,keys,to{Asc,Desc}List -- it was forbidden to+-- inline it before phase 0, otherwise the fusion rules would not fire at all.+{-# NOINLINE[0] elems #-}+{-# NOINLINE[0] keys #-}+{-# NOINLINE[0] toAscList #-}+{-# NOINLINE[0] toDescList #-}+{-# RULES "Word64Map.elems" [~1] forall m . elems m = build (\c n -> foldrFB (\_ x xs -> c x xs) n m) #-}+{-# RULES "Word64Map.elemsBack" [1] foldrFB (\_ x xs -> x : xs) [] = elems #-}+{-# RULES "Word64Map.keys" [~1] forall m . keys m = build (\c n -> foldrFB (\k _ xs -> c k xs) n m) #-}+{-# RULES "Word64Map.keysBack" [1] foldrFB (\k _ xs -> k : xs) [] = keys #-}+{-# RULES "Word64Map.toAscList" [~1] forall m . toAscList m = build (\c n -> foldrFB (\k x xs -> c (k,x) xs) n m) #-}+{-# RULES "Word64Map.toAscListBack" [1] foldrFB (\k x xs -> (k, x) : xs) [] = toAscList #-}+{-# RULES "Word64Map.toDescList" [~1] forall m . toDescList m = build (\c n -> foldlFB (\xs k x -> c (k,x) xs) n m) #-}+{-# RULES "Word64Map.toDescListBack" [1] foldlFB (\xs k x -> (k, x) : xs) [] = toDescList #-}+#endif+++-- | \(O(n \min(n,W))\). Create a map from a list of key\/value pairs.+--+-- > fromList [] == empty+-- > fromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]+-- > fromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]++fromList :: [(Key,a)] -> Word64Map a+fromList xs+  = Foldable.foldl' ins empty xs+  where+    ins t (k,x)  = insert k x t++-- | \(O(n \min(n,W))\). Create a map from a list of key\/value pairs with a combining function. See also 'fromAscListWith'.+--+-- > fromListWith (++) [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "ab"), (5, "cba")]+-- > fromListWith (++) [] == empty++fromListWith :: (a -> a -> a) -> [(Key,a)] -> Word64Map a+fromListWith f xs+  = fromListWithKey (\_ x y -> f x y) xs++-- | \(O(n \min(n,W))\). Build a map from a list of key\/value pairs with a combining function. See also fromAscListWithKey'.+--+-- > let f key new_value old_value = show key ++ ":" ++ new_value ++ "|" ++ old_value+-- > fromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "3:a|b"), (5, "5:c|5:b|a")]+-- > fromListWithKey f [] == empty++fromListWithKey :: (Key -> a -> a -> a) -> [(Key,a)] -> Word64Map a+fromListWithKey f xs+  = Foldable.foldl' ins empty xs+  where+    ins t (k,x) = insertWithKey f k x t++-- | \(O(n)\). Build a map from a list of key\/value pairs where+-- the keys are in ascending order.+--+-- > fromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]+-- > fromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]++fromAscList :: [(Key,a)] -> Word64Map a+fromAscList = fromMonoListWithKey Nondistinct (\_ x _ -> x)+{-# NOINLINE fromAscList #-}++-- | \(O(n)\). Build a map from a list of key\/value pairs where+-- the keys are in ascending order, with a combining function on equal keys.+-- /The precondition (input list is ascending) is not checked./+--+-- > fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]++fromAscListWith :: (a -> a -> a) -> [(Key,a)] -> Word64Map a+fromAscListWith f = fromMonoListWithKey Nondistinct (\_ x y -> f x y)+{-# NOINLINE fromAscListWith #-}++-- | \(O(n)\). Build a map from a list of key\/value pairs where+-- the keys are in ascending order, with a combining function on equal keys.+-- /The precondition (input list is ascending) is not checked./+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "5:b|a")]++fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key,a)] -> Word64Map a+fromAscListWithKey f = fromMonoListWithKey Nondistinct f+{-# NOINLINE fromAscListWithKey #-}++-- | \(O(n)\). Build a map from a list of key\/value pairs where+-- the keys are in ascending order and all distinct.+-- /The precondition (input list is strictly ascending) is not checked./+--+-- > fromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]++fromDistinctAscList :: [(Key,a)] -> Word64Map a+fromDistinctAscList = fromMonoListWithKey Distinct (\_ x _ -> x)+{-# NOINLINE fromDistinctAscList #-}++-- | \(O(n)\). Build a map from a list of key\/value pairs with monotonic keys+-- and a combining function.+--+-- The precise conditions under which this function works are subtle:+-- For any branch mask, keys with the same prefix w.r.t. the branch+-- mask must occur consecutively in the list.++fromMonoListWithKey :: Distinct -> (Key -> a -> a -> a) -> [(Key,a)] -> Word64Map a+fromMonoListWithKey distinct f = go+  where+    go []              = Nil+    go ((kx,vx) : zs1) = addAll' kx vx zs1++    -- `addAll'` collects all keys equal to `kx` into a single value,+    -- and then proceeds with `addAll`.+    addAll' !kx vx []+        = Tip kx vx+    addAll' !kx vx ((ky,vy) : zs)+        | Nondistinct <- distinct, kx == ky+        = let v = f kx vy vx in addAll' ky v zs+        -- inlined: | otherwise = addAll kx (Tip kx vx) (ky : zs)+        | m <- branchMask kx ky+        , Inserted ty zs' <- addMany' m ky vy zs+        = addAll kx (linkWithMask m ky ty {-kx-} (Tip kx vx)) zs'++    -- for `addAll` and `addMany`, kx is /a/ key inside the tree `tx`+    -- `addAll` consumes the rest of the list, adding to the tree `tx`+    addAll !_kx !tx []+        = tx+    addAll !kx !tx ((ky,vy) : zs)+        | m <- branchMask kx ky+        , Inserted ty zs' <- addMany' m ky vy zs+        = addAll kx (linkWithMask m ky ty {-kx-} tx) zs'++    -- `addMany'` is similar to `addAll'`, but proceeds with `addMany'`.+    addMany' !_m !kx vx []+        = Inserted (Tip kx vx) []+    addMany' !m !kx vx zs0@((ky,vy) : zs)+        | Nondistinct <- distinct, kx == ky+        = let v = f kx vy vx in addMany' m ky v zs+        -- inlined: | otherwise = addMany m kx (Tip kx vx) (ky : zs)+        | mask kx m /= mask ky m+        = Inserted (Tip kx vx) zs0+        | mxy <- branchMask kx ky+        , Inserted ty zs' <- addMany' mxy ky vy zs+        = addMany m kx (linkWithMask mxy ky ty {-kx-} (Tip kx vx)) zs'++    -- `addAll` adds to `tx` all keys whose prefix w.r.t. `m` agrees with `kx`.+    addMany !_m !_kx tx []+        = Inserted tx []+    addMany !m !kx tx zs0@((ky,vy) : zs)+        | mask kx m /= mask ky m+        = Inserted tx zs0+        | mxy <- branchMask kx ky+        , Inserted ty zs' <- addMany' mxy ky vy zs+        = addMany m kx (linkWithMask mxy ky ty {-kx-} tx) zs'+{-# INLINE fromMonoListWithKey #-}++data Inserted a = Inserted !(Word64Map a) ![(Key,a)]++data Distinct = Distinct | Nondistinct++{--------------------------------------------------------------------+  Eq+--------------------------------------------------------------------}+instance Eq a => Eq (Word64Map a) where+  t1 == t2  = equal t1 t2+  t1 /= t2  = nequal t1 t2++equal :: Eq a => Word64Map a -> Word64Map a -> Bool+equal (Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)+  = (m1 == m2) && (p1 == p2) && (equal l1 l2) && (equal r1 r2)+equal (Tip kx x) (Tip ky y)+  = (kx == ky) && (x==y)+equal Nil Nil = True+equal _   _   = False++nequal :: Eq a => Word64Map a -> Word64Map a -> Bool+nequal (Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)+  = (m1 /= m2) || (p1 /= p2) || (nequal l1 l2) || (nequal r1 r2)+nequal (Tip kx x) (Tip ky y)+  = (kx /= ky) || (x/=y)+nequal Nil Nil = False+nequal _   _   = True++-- | @since 0.5.9+instance Eq1 Word64Map where+  liftEq eq (Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)+    = (m1 == m2) && (p1 == p2) && (liftEq eq l1 l2) && (liftEq eq r1 r2)+  liftEq eq (Tip kx x) (Tip ky y)+    = (kx == ky) && (eq x y)+  liftEq _eq Nil Nil = True+  liftEq _eq _   _   = False++{--------------------------------------------------------------------+  Ord+--------------------------------------------------------------------}++instance Ord a => Ord (Word64Map a) where+    compare m1 m2 = compare (toList m1) (toList m2)++-- | @since 0.5.9+instance Ord1 Word64Map where+  liftCompare cmp m n =+    liftCompare (liftCompare cmp) (toList m) (toList n)++{--------------------------------------------------------------------+  Functor+--------------------------------------------------------------------}++instance Functor Word64Map where+    fmap = map++#ifdef __GLASGOW_HASKELL__+    a <$ Bin p m l r = Bin p m (a <$ l) (a <$ r)+    a <$ Tip k _     = Tip k a+    _ <$ Nil         = Nil+#endif++{--------------------------------------------------------------------+  Show+--------------------------------------------------------------------}++instance Show a => Show (Word64Map a) where+  showsPrec d m   = showParen (d > 10) $+    showString "fromList " . shows (toList m)++-- | @since 0.5.9+instance Show1 Word64Map where+    liftShowsPrec sp sl d m =+        showsUnaryWith (liftShowsPrec sp' sl') "fromList" d (toList m)+      where+        sp' = liftShowsPrec sp sl+        sl' = liftShowList sp sl++{--------------------------------------------------------------------+  Read+--------------------------------------------------------------------}+instance (Read e) => Read (Word64Map e) where+#ifdef __GLASGOW_HASKELL__+  readPrec = parens $ prec 10 $ do+    Ident "fromList" <- lexP+    xs <- readPrec+    return (fromList xs)++  readListPrec = readListPrecDefault+#else+  readsPrec p = readParen (p > 10) $ \ r -> do+    ("fromList",s) <- lex r+    (xs,t) <- reads s+    return (fromList xs,t)+#endif++-- | @since 0.5.9+instance Read1 Word64Map where+    liftReadsPrec rp rl = readsData $+        readsUnaryWith (liftReadsPrec rp' rl') "fromList" fromList+      where+        rp' = liftReadsPrec rp rl+        rl' = liftReadList rp rl++{--------------------------------------------------------------------+  Helpers+--------------------------------------------------------------------}+{--------------------------------------------------------------------+  Link+--------------------------------------------------------------------}+link :: Prefix -> Word64Map a -> Prefix -> Word64Map a -> Word64Map a+link p1 t1 p2 t2 = linkWithMask (branchMask p1 p2) p1 t1 {-p2-} t2+{-# INLINE link #-}++-- `linkWithMask` is useful when the `branchMask` has already been computed+linkWithMask :: Mask -> Prefix -> Word64Map a -> Word64Map a -> Word64Map a+linkWithMask m p1 t1 {-p2-} t2+  | zero p1 m = Bin p m t1 t2+  | otherwise = Bin p m t2 t1+  where+    p = mask p1 m+{-# INLINE linkWithMask #-}++{--------------------------------------------------------------------+  @bin@ assures that we never have empty trees within a tree.+--------------------------------------------------------------------}+bin :: Prefix -> Mask -> Word64Map a -> Word64Map a -> Word64Map a+bin _ _ l Nil = l+bin _ _ Nil r = r+bin p m l r   = Bin p m l r+{-# INLINE bin #-}++-- binCheckLeft only checks that the left subtree is non-empty+binCheckLeft :: Prefix -> Mask -> Word64Map a -> Word64Map a -> Word64Map a+binCheckLeft _ _ Nil r = r+binCheckLeft p m l r   = Bin p m l r+{-# INLINE binCheckLeft #-}++-- binCheckRight only checks that the right subtree is non-empty+binCheckRight :: Prefix -> Mask -> Word64Map a -> Word64Map a -> Word64Map a+binCheckRight _ _ l Nil = l+binCheckRight p m l r   = Bin p m l r+{-# INLINE binCheckRight #-}++{--------------------------------------------------------------------+  Endian independent bit twiddling+--------------------------------------------------------------------}++-- | Should this key follow the left subtree of a 'Bin' with switching+-- bit @m@? N.B., the answer is only valid when @match i p m@ is true.+zero :: Key -> Mask -> Bool+zero i m+  = (natFromInt i) .&. (natFromInt m) == 0+{-# INLINE zero #-}++nomatch,match :: Key -> Prefix -> Mask -> Bool++-- | Does the key @i@ differ from the prefix @p@ before getting to+-- the switching bit @m@?+nomatch i p m+  = (mask i m) /= p+{-# INLINE nomatch #-}++-- | Does the key @i@ match the prefix @p@ (up to but not including+-- bit @m@)?+match i p m+  = (mask i m) == p+{-# INLINE match #-}+++-- | The prefix of key @i@ up to (but not including) the switching+-- bit @m@.+mask :: Key -> Mask -> Prefix+mask i m+  = maskW (natFromInt i) (natFromInt m)+{-# INLINE mask #-}+++{--------------------------------------------------------------------+  Big endian operations+--------------------------------------------------------------------}++-- | The prefix of key @i@ up to (but not including) the switching+-- bit @m@.+maskW :: Nat -> Nat -> Prefix+maskW i m+  = intFromNat (i .&. ((-m) `xor` m))+{-# INLINE maskW #-}++-- | Does the left switching bit specify a shorter prefix?+shorter :: Mask -> Mask -> Bool+shorter m1 m2+  = (natFromInt m1) > (natFromInt m2)+{-# INLINE shorter #-}++-- | The first switching bit where the two prefixes disagree.+branchMask :: Prefix -> Prefix -> Mask+branchMask p1 p2+  = intFromNat (highestBitMask (natFromInt p1 `xor` natFromInt p2))+{-# INLINE branchMask #-}++{--------------------------------------------------------------------+  Utilities+--------------------------------------------------------------------}++-- | \(O(1)\).  Decompose a map into pieces based on the structure+-- of the underlying tree. This function is useful for consuming a+-- map in parallel.+--+-- No guarantee is made as to the sizes of the pieces; an internal, but+-- deterministic process determines this.  However, it is guaranteed that the+-- pieces returned will be in ascending order (all elements in the first submap+-- less than all elements in the second, and so on).+--+-- Examples:+--+-- > splitRoot (fromList (zip [1..6::Int] ['a'..])) ==+-- >   [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d'),(5,'e'),(6,'f')]]+--+-- > splitRoot empty == []+--+--  Note that the current implementation does not return more than two submaps,+--  but you should not depend on this behaviour because it can change in the+--  future without notice.+splitRoot :: Word64Map a -> [Word64Map a]+splitRoot orig =+  case orig of+    Nil -> []+    x@(Tip _ _) -> [x]+    Bin _ m l r | m < 0 -> [r, l]+                | otherwise -> [l, r]+{-# INLINE splitRoot #-}+++{--------------------------------------------------------------------+  Debugging+--------------------------------------------------------------------}++-- | \(O(n \min(n,W))\). Show the tree that implements the map. The tree is shown+-- in a compressed, hanging format.+showTree :: Show a => Word64Map a -> String+showTree s+  = showTreeWith True False s+++{- | \(O(n \min(n,W))\). The expression (@'showTreeWith' hang wide map@) shows+ the tree that implements the map. If @hang@ is+ 'True', a /hanging/ tree is shown otherwise a rotated tree is shown. If+ @wide@ is 'True', an extra wide version is shown.+-}+showTreeWith :: Show a => Bool -> Bool -> Word64Map a -> String+showTreeWith hang wide t+  | hang      = (showsTreeHang wide [] t) ""+  | otherwise = (showsTree wide [] [] t) ""++showsTree :: Show a => Bool -> [String] -> [String] -> Word64Map a -> ShowS+showsTree wide lbars rbars t = case t of+  Bin p m l r ->+    showsTree wide (withBar rbars) (withEmpty rbars) r .+    showWide wide rbars .+    showsBars lbars . showString (showBin p m) . showString "\n" .+    showWide wide lbars .+    showsTree wide (withEmpty lbars) (withBar lbars) l+  Tip k x ->+    showsBars lbars .+    showString " " . shows k . showString ":=" . shows x . showString "\n"+  Nil -> showsBars lbars . showString "|\n"++showsTreeHang :: Show a => Bool -> [String] -> Word64Map a -> ShowS+showsTreeHang wide bars t = case t of+  Bin p m l r ->+    showsBars bars . showString (showBin p m) . showString "\n" .+    showWide wide bars .+    showsTreeHang wide (withBar bars) l .+    showWide wide bars .+    showsTreeHang wide (withEmpty bars) r+  Tip k x ->+    showsBars bars .+    showString " " . shows k . showString ":=" . shows x . showString "\n"+  Nil -> showsBars bars . showString "|\n"++showBin :: Prefix -> Mask -> String+showBin _ _+  = "*" -- ++ show (p,m)++showWide :: Bool -> [String] -> String -> String+showWide wide bars+  | wide      = showString (concat (reverse bars)) . showString "|\n"+  | otherwise = id++showsBars :: [String] -> ShowS+showsBars bars+  = case bars of+      [] -> id+      _ : tl -> showString (concat (reverse tl)) . showString node++node :: String+node = "+--"++withBar, withEmpty :: [String] -> [String]+withBar bars   = "|  ":bars+withEmpty bars = "   ":bars
+ GHC/Data/Word64Map/Lazy.hs view
@@ -0,0 +1,237 @@+{-# LANGUAGE CPP #-}+#if !defined(TESTING) && defined(__GLASGOW_HASKELL__)+{-# LANGUAGE Safe #-}+#endif++#include "containers.h"++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Word64Map.Lazy+-- Copyright   :  (c) Daan Leijen 2002+--                (c) Andriy Palamarchuk 2008+-- License     :  BSD-style+-- Maintainer  :  libraries@haskell.org+-- Portability :  portable+--+--+-- = Finite Word64 Maps (lazy interface)+--+-- The @'Word64Map' v@ type represents a finite map (sometimes called a dictionary)+-- from keys of type @Word64@ to values of type @v@.+--+-- The functions in "Data.Word64Map.Strict" are careful to force values before+-- installing them in an 'Word64Map'. This is usually more efficient in cases where+-- laziness is not essential. The functions in this module do not do so.+--+-- For a walkthrough of the most commonly used functions see the+-- <https://haskell-containers.readthedocs.io/en/latest/map.html maps introduction>.+--+-- This module is intended to be imported qualified, to avoid name clashes with+-- Prelude functions:+--+-- > import Data.Word64Map.Lazy (Word64Map)+-- > import qualified Data.Word64Map.Lazy as Word64Map+--+-- Note that the implementation is generally /left-biased/. Functions that take+-- two maps as arguments and combine them, such as `union` and `intersection`,+-- prefer the values in the first argument to those in the second.+--+--+-- == Detailed performance information+--+-- The amortized running time is given for each operation, with \(n\) referring to+-- the number of entries in the map and \(W\) referring to the number of bits in+-- an 'Word64' (64).+--+-- Benchmarks comparing "Data.Word64Map.Lazy" with other dictionary+-- implementations can be found at https://github.com/haskell-perf/dictionaries.+--+--+-- == Implementation+--+-- The implementation is based on /big-endian patricia trees/.  This data+-- structure performs especially well on binary operations like 'union' and+-- 'intersection'. Additionally, benchmarks show that it is also (much) faster+-- on insertions and deletions when compared to a generic size-balanced map+-- implementation (see "Data.Map").+--+--    * Chris Okasaki and Andy Gill,  \"/Fast Mergeable Integer Maps/\",+--      Workshop on ML, September 1998, pages 77-86,+--      <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.37.5452>+--+--    * D.R. Morrison, \"/PATRICIA -- Practical Algorithm To Retrieve Information Coded In Alphanumeric/\",+--      Journal of the ACM, 15(4), October 1968, pages 514-534.+--+-----------------------------------------------------------------------------++module GHC.Data.Word64Map.Lazy (+    -- * Map type+#if !defined(TESTING)+    Word64Map, Key          -- instance Eq,Show+#else+    Word64Map(..), Key          -- instance Eq,Show+#endif++    -- * Construction+    , empty+    , singleton+    , fromSet++    -- ** From Unordered Lists+    , fromList+    , fromListWith+    , fromListWithKey++    -- ** From Ascending Lists+    , fromAscList+    , fromAscListWith+    , fromAscListWithKey+    , fromDistinctAscList++    -- * Insertion+    , insert+    , insertWith+    , insertWithKey+    , insertLookupWithKey++    -- * Deletion\/Update+    , delete+    , adjust+    , adjustWithKey+    , update+    , updateWithKey+    , updateLookupWithKey+    , alter+    , alterF++    -- * Query+    -- ** Lookup+    , WM.lookup+    , (!?)+    , (!)+    , findWithDefault+    , member+    , notMember+    , lookupLT+    , lookupGT+    , lookupLE+    , lookupGE++    -- ** Size+    , WM.null+    , size++    -- * Combine++    -- ** Union+    , union+    , unionWith+    , unionWithKey+    , unions+    , unionsWith++    -- ** Difference+    , difference+    , (\\)+    , differenceWith+    , differenceWithKey++    -- ** Intersection+    , intersection+    , intersectionWith+    , intersectionWithKey++    -- ** Disjoint+    , disjoint++    -- ** Compose+    , compose++    -- ** Universal combining function+    , mergeWithKey++    -- * Traversal+    -- ** Map+    , WM.map+    , mapWithKey+    , traverseWithKey+    , traverseMaybeWithKey+    , mapAccum+    , mapAccumWithKey+    , mapAccumRWithKey+    , mapKeys+    , mapKeysWith+    , mapKeysMonotonic++    -- * Folds+    , WM.foldr+    , WM.foldl+    , foldrWithKey+    , foldlWithKey+    , foldMapWithKey++    -- ** Strict folds+    , foldr'+    , foldl'+    , foldrWithKey'+    , foldlWithKey'++    -- * Conversion+    , elems+    , keys+    , assocs+    , keysSet++    -- ** Lists+    , toList++    -- ** Ordered lists+    , toAscList+    , toDescList++    -- * Filter+    , WM.filter+    , filterWithKey+    , restrictKeys+    , withoutKeys+    , partition+    , partitionWithKey++    , takeWhileAntitone+    , dropWhileAntitone+    , spanAntitone++    , mapMaybe+    , mapMaybeWithKey+    , mapEither+    , mapEitherWithKey++    , split+    , splitLookup+    , splitRoot++    -- * Submap+    , isSubmapOf, isSubmapOfBy+    , isProperSubmapOf, isProperSubmapOfBy++    -- * Min\/Max+    , lookupMin+    , lookupMax+    , findMin+    , findMax+    , deleteMin+    , deleteMax+    , deleteFindMin+    , deleteFindMax+    , updateMin+    , updateMax+    , updateMinWithKey+    , updateMaxWithKey+    , minView+    , maxView+    , minViewWithKey+    , maxViewWithKey+    ) where++import GHC.Data.Word64Map.Internal as WM
+ GHC/Data/Word64Map/Strict.hs view
@@ -0,0 +1,257 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE BangPatterns #-}+#if !defined(TESTING) && defined(__GLASGOW_HASKELL__)+{-# LANGUAGE Trustworthy #-}+#endif++#include "containers.h"++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Word64Map.Strict+-- Copyright   :  (c) Daan Leijen 2002+--                (c) Andriy Palamarchuk 2008+-- License     :  BSD-style+-- Maintainer  :  libraries@haskell.org+-- Portability :  portable+--+--+-- = Finite Word64 Maps (strict interface)+--+-- The @'Word64Map' v@ type represents a finite map (sometimes called a dictionary)+-- from key of type @Word64@ to values of type @v@.+--+-- Each function in this module is careful to force values before installing+-- them in an 'Word64Map'. This is usually more efficient when laziness is not+-- necessary. When laziness /is/ required, use the functions in+-- "Data.Word64Map.Lazy".+--+-- In particular, the functions in this module obey the following law:+--+--  - If all values stored in all maps in the arguments are in WHNF, then all+--    values stored in all maps in the results will be in WHNF once those maps+--    are evaluated.+--+-- For a walkthrough of the most commonly used functions see the+-- <https://haskell-containers.readthedocs.io/en/latest/map.html maps introduction>.+--+-- This module is intended to be imported qualified, to avoid name clashes with+-- Prelude functions:+--+-- > import Data.Word64Map.Strict (Word64Map)+-- > import qualified Data.Word64Map.Strict as Word64Map+--+-- Note that the implementation is generally /left-biased/. Functions that take+-- two maps as arguments and combine them, such as `union` and `intersection`,+-- prefer the values in the first argument to those in the second.+--+--+-- == Detailed performance information+--+-- The amortized running time is given for each operation, with \(n\) referring to+-- the number of entries in the map and \(W\) referring to the number of bits in+-- an 'Word64' (64).+--+-- Benchmarks comparing "Data.Word64Map.Strict" with other dictionary+-- implementations can be found at https://github.com/haskell-perf/dictionaries.+--+--+-- == Warning+--+-- The 'Word64Map' type is shared between the lazy and strict modules, meaning that+-- the same 'Word64Map' value can be passed to functions in both modules. This+-- means that the 'Functor', 'Traversable' and 'Data.Data.Data' instances are+-- the same as for the "Data.Word64Map.Lazy" module, so if they are used the+-- resulting map may contain suspended values (thunks).+--+--+-- == Implementation+--+-- The implementation is based on /big-endian patricia trees/.  This data+-- structure performs especially well on binary operations like 'union' and+-- 'intersection'. Additionally, benchmarks show that it is also (much) faster+-- on insertions and deletions when compared to a generic size-balanced map+-- implementation (see "Data.Map").+--+--    * Chris Okasaki and Andy Gill,  \"/Fast Mergeable Integer Maps/\",+--      Workshop on ML, September 1998, pages 77-86,+--      <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.37.5452>+--+--    * D.R. Morrison, \"/PATRICIA -- Practical Algorithm To Retrieve Information Coded In Alphanumeric/\",+--      Journal of the ACM, 15(4), October 1968, pages 514-534.+--+-----------------------------------------------------------------------------++-- See the notes at the beginning of Data.Word64Map.Internal.++module GHC.Data.Word64Map.Strict (+    -- * Map type+#if !defined(TESTING)+    Word64Map, Key          -- instance Eq,Show+#else+    Word64Map(..), Key          -- instance Eq,Show+#endif++    -- * Construction+    , empty+    , singleton+    , fromSet++    -- ** From Unordered Lists+    , fromList+    , fromListWith+    , fromListWithKey++    -- ** From Ascending Lists+    , fromAscList+    , fromAscListWith+    , fromAscListWithKey+    , fromDistinctAscList++    -- * Insertion+    , insert+    , insertWith+    , insertWithKey+    , insertLookupWithKey++    -- * Deletion\/Update+    , delete+    , adjust+    , adjustWithKey+    , update+    , updateWithKey+    , updateLookupWithKey+    , alter+    , alterF++    -- * Query+    -- ** Lookup+    , lookup+    , (!?)+    , (!)+    , findWithDefault+    , member+    , notMember+    , lookupLT+    , lookupGT+    , lookupLE+    , lookupGE++    -- ** Size+    , null+    , size++    -- * Combine++    -- ** Union+    , union+    , unionWith+    , unionWithKey+    , unions+    , unionsWith++    -- ** Difference+    , difference+    , (\\)+    , differenceWith+    , differenceWithKey++    -- ** Intersection+    , intersection+    , intersectionWith+    , intersectionWithKey++    -- ** Disjoint+    , disjoint++    -- ** Compose+    , compose++    -- ** Universal combining function+    , mergeWithKey++    -- * Traversal+    -- ** Map+    , map+    , mapWithKey+    , traverseWithKey+    , traverseMaybeWithKey+    , mapAccum+    , mapAccumWithKey+    , mapAccumRWithKey+    , mapKeys+    , mapKeysWith+    , mapKeysMonotonic++    -- * Folds+    , foldr+    , foldl+    , foldrWithKey+    , foldlWithKey+    , foldMapWithKey++    -- ** Strict folds+    , foldr'+    , foldl'+    , foldrWithKey'+    , foldlWithKey'++    -- * Conversion+    , elems+    , keys+    , assocs+    , keysSet++    -- ** Lists+    , toList++-- ** Ordered lists+    , toAscList+    , toDescList++    -- * Filter+    , filter+    , filterWithKey+    , restrictKeys+    , withoutKeys+    , partition+    , partitionWithKey++    , takeWhileAntitone+    , dropWhileAntitone+    , spanAntitone++    , mapMaybe+    , mapMaybeWithKey+    , mapEither+    , mapEitherWithKey++    , split+    , splitLookup+    , splitRoot++    -- * Submap+    , isSubmapOf, isSubmapOfBy+    , isProperSubmapOf, isProperSubmapOfBy++    -- * Min\/Max+    , lookupMin+    , lookupMax+    , findMin+    , findMax+    , deleteMin+    , deleteMax+    , deleteFindMin+    , deleteFindMax+    , updateMin+    , updateMax+    , updateMinWithKey+    , updateMaxWithKey+    , minView+    , maxView+    , minViewWithKey+    , maxViewWithKey+    ) where++import GHC.Data.Word64Map.Strict.Internal+import Prelude ()
+ GHC/Data/Word64Map/Strict/Internal.hs view
@@ -0,0 +1,1208 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE PatternGuards #-}++{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}++#include "containers.h"++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Word64Map.Strict.Internal+-- Copyright   :  (c) Daan Leijen 2002+--                (c) Andriy Palamarchuk 2008+-- License     :  BSD-style+-- Maintainer  :  libraries@haskell.org+-- Portability :  portable+--+--+-- = Finite Int Maps (strict interface)+--+-- The @'Word64Map' v@ type represents a finite map (sometimes called a dictionary)+-- from key of type @Int@ to values of type @v@.+--+-- Each function in this module is careful to force values before installing+-- them in an 'Word64Map'. This is usually more efficient when laziness is not+-- necessary. When laziness /is/ required, use the functions in+-- "Data.Word64Map.Lazy".+--+-- In particular, the functions in this module obey the following law:+--+--  - If all values stored in all maps in the arguments are in WHNF, then all+--    values stored in all maps in the results will be in WHNF once those maps+--    are evaluated.+--+-- For a walkthrough of the most commonly used functions see the+-- <https://haskell-containers.readthedocs.io/en/latest/map.html maps introduction>.+--+-- This module is intended to be imported qualified, to avoid name clashes with+-- Prelude functions:+--+-- > import Data.Word64Map.Strict (Word64Map)+-- > import qualified Data.Word64Map.Strict as Word64Map+--+-- Note that the implementation is generally /left-biased/. Functions that take+-- two maps as arguments and combine them, such as `union` and `intersection`,+-- prefer the values in the first argument to those in the second.+--+--+-- == Detailed performance information+--+-- The amortized running time is given for each operation, with \(n\) referring to+-- the number of entries in the map and \(W\) referring to the number of bits in+-- an 'Int' (32 or 64).+--+-- Benchmarks comparing "Data.Word64Map.Strict" with other dictionary+-- implementations can be found at https://github.com/haskell-perf/dictionaries.+--+--+-- == Warning+--+-- The 'Word64Map' type is shared between the lazy and strict modules, meaning that+-- the same 'Word64Map' value can be passed to functions in both modules. This+-- means that the 'Functor', 'Traversable' and 'Data.Data.Data' instances are+-- the same as for the "Data.Word64Map.Lazy" module, so if they are used the+-- resulting map may contain suspended values (thunks).+--+--+-- == Implementation+--+-- The implementation is based on /big-endian patricia trees/.  This data+-- structure performs especially well on binary operations like 'union' and+-- 'intersection'. Additionally, benchmarks show that it is also (much) faster+-- on insertions and deletions when compared to a generic size-balanced map+-- implementation (see "Data.Map").+--+--    * Chris Okasaki and Andy Gill,  \"/Fast Mergeable Integer Maps/\",+--      Workshop on ML, September 1998, pages 77-86,+--      <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.37.5452>+--+--    * D.R. Morrison, \"/PATRICIA -- Practical Algorithm To Retrieve Information Coded In Alphanumeric/\",+--      Journal of the ACM, 15(4), October 1968, pages 514-534.+--+-----------------------------------------------------------------------------++-- See the notes at the beginning of Data.Word64Map.Internal.++module GHC.Data.Word64Map.Strict.Internal (+    -- * Map type+#if !defined(TESTING)+    Word64Map, Key          -- instance Eq,Show+#else+    Word64Map(..), Key          -- instance Eq,Show+#endif++    -- * Construction+    , empty+    , singleton+    , fromSet++    -- ** From Unordered Lists+    , fromList+    , fromListWith+    , fromListWithKey++    -- ** From Ascending Lists+    , fromAscList+    , fromAscListWith+    , fromAscListWithKey+    , fromDistinctAscList++    -- * Insertion+    , insert+    , insertWith+    , insertWithKey+    , insertLookupWithKey++    -- * Deletion\/Update+    , delete+    , adjust+    , adjustWithKey+    , update+    , updateWithKey+    , updateLookupWithKey+    , alter+    , alterF++    -- * Query+    -- ** Lookup+    , lookup+    , (!?)+    , (!)+    , findWithDefault+    , member+    , notMember+    , lookupLT+    , lookupGT+    , lookupLE+    , lookupGE++    -- ** Size+    , null+    , size++    -- * Combine++    -- ** Union+    , union+    , unionWith+    , unionWithKey+    , unions+    , unionsWith++    -- ** Difference+    , difference+    , (\\)+    , differenceWith+    , differenceWithKey++    -- ** Intersection+    , intersection+    , intersectionWith+    , intersectionWithKey++    -- ** Disjoint+    , disjoint++    -- ** Compose+    , compose++    -- ** Universal combining function+    , mergeWithKey++    -- * Traversal+    -- ** Map+    , map+    , mapWithKey+    , traverseWithKey+    , traverseMaybeWithKey+    , mapAccum+    , mapAccumWithKey+    , mapAccumRWithKey+    , mapKeys+    , mapKeysWith+    , mapKeysMonotonic++    -- * Folds+    , foldr+    , foldl+    , foldrWithKey+    , foldlWithKey+    , foldMapWithKey++    -- ** Strict folds+    , foldr'+    , foldl'+    , foldrWithKey'+    , foldlWithKey'++    -- * Conversion+    , elems+    , keys+    , assocs+    , keysSet++    -- ** Lists+    , toList++-- ** Ordered lists+    , toAscList+    , toDescList++    -- * Filter+    , filter+    , filterWithKey+    , restrictKeys+    , withoutKeys+    , partition+    , partitionWithKey++    , takeWhileAntitone+    , dropWhileAntitone+    , spanAntitone++    , mapMaybe+    , mapMaybeWithKey+    , mapEither+    , mapEitherWithKey++    , split+    , splitLookup+    , splitRoot++    -- * Submap+    , isSubmapOf, isSubmapOfBy+    , isProperSubmapOf, isProperSubmapOfBy++    -- * Min\/Max+    , lookupMin+    , lookupMax+    , findMin+    , findMax+    , deleteMin+    , deleteMax+    , deleteFindMin+    , deleteFindMax+    , updateMin+    , updateMax+    , updateMinWithKey+    , updateMaxWithKey+    , minView+    , maxView+    , minViewWithKey+    , maxViewWithKey+    ) where++import GHC.Prelude.Basic hiding+  (lookup, filter, foldr, foldl, foldl', null, map)++import qualified GHC.Data.Word64Map.Internal as L+import GHC.Data.Word64Map.Internal+  ( Word64Map (..)+  , Key+  , mask+  , branchMask+  , nomatch+  , zero+  , natFromInt+  , intFromNat+  , bin+  , binCheckLeft+  , binCheckRight+  , link+  , linkWithMask++  , (\\)+  , (!)+  , (!?)+  , empty+  , assocs+  , filter+  , filterWithKey+  , findMin+  , findMax+  , foldMapWithKey+  , foldr+  , foldl+  , foldr'+  , foldl'+  , foldlWithKey+  , foldrWithKey+  , foldlWithKey'+  , foldrWithKey'+  , keysSet+  , mergeWithKey'+  , compose+  , delete+  , deleteMin+  , deleteMax+  , deleteFindMax+  , deleteFindMin+  , difference+  , elems+  , intersection+  , disjoint+  , isProperSubmapOf+  , isProperSubmapOfBy+  , isSubmapOf+  , isSubmapOfBy+  , lookup+  , lookupLE+  , lookupGE+  , lookupLT+  , lookupGT+  , lookupMin+  , lookupMax+  , minView+  , maxView+  , minViewWithKey+  , maxViewWithKey+  , keys+  , mapKeys+  , mapKeysMonotonic+  , member+  , notMember+  , null+  , partition+  , partitionWithKey+  , takeWhileAntitone+  , dropWhileAntitone+  , spanAntitone+  , restrictKeys+  , size+  , split+  , splitLookup+  , splitRoot+  , toAscList+  , toDescList+  , toList+  , union+  , unions+  , withoutKeys+  )+import qualified GHC.Data.Word64Set.Internal as Word64Set+import GHC.Utils.Containers.Internal.BitUtil+import GHC.Utils.Containers.Internal.StrictPair+import qualified Data.Foldable as Foldable++{--------------------------------------------------------------------+  Query+--------------------------------------------------------------------}++-- | \(O(\min(n,W))\). The expression @('findWithDefault' def k map)@+-- returns the value at key @k@ or returns @def@ when the key is not an+-- element of the map.+--+-- > findWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'+-- > findWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'++-- See Word64Map.Internal.Note: Local 'go' functions and capturing]+findWithDefault :: a -> Key -> Word64Map a -> a+findWithDefault def !k = go+  where+    go (Bin p m l r) | nomatch k p m = def+                     | zero k m  = go l+                     | otherwise = go r+    go (Tip kx x) | k == kx   = x+                  | otherwise = def+    go Nil = def++{--------------------------------------------------------------------+  Construction+--------------------------------------------------------------------}+-- | \(O(1)\). A map of one element.+--+-- > singleton 1 'a'        == fromList [(1, 'a')]+-- > size (singleton 1 'a') == 1++singleton :: Key -> a -> Word64Map a+singleton k !x+  = Tip k x+{-# INLINE singleton #-}++{--------------------------------------------------------------------+  Insert+--------------------------------------------------------------------}+-- | \(O(\min(n,W))\). Insert a new key\/value pair in the map.+-- If the key is already present in the map, the associated value is+-- replaced with the supplied value, i.e. 'insert' is equivalent to+-- @'insertWith' 'const'@.+--+-- > insert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]+-- > insert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]+-- > insert 5 'x' empty                         == singleton 5 'x'++insert :: Key -> a -> Word64Map a -> Word64Map a+insert !k !x t =+  case t of+    Bin p m l r+      | nomatch k p m -> link k (Tip k x) p t+      | zero k m      -> Bin p m (insert k x l) r+      | otherwise     -> Bin p m l (insert k x r)+    Tip ky _+      | k==ky         -> Tip k x+      | otherwise     -> link k (Tip k x) ky t+    Nil -> Tip k x++-- right-biased insertion, used by 'union'+-- | \(O(\min(n,W))\). Insert with a combining function.+-- @'insertWith' f key value mp@+-- will insert the pair (key, value) into @mp@ if key does+-- not exist in the map. If the key does exist, the function will+-- insert @f new_value old_value@.+--+-- > insertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]+-- > insertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]+-- > insertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"++insertWith :: (a -> a -> a) -> Key -> a -> Word64Map a -> Word64Map a+insertWith f k x t+  = insertWithKey (\_ x' y' -> f x' y') k x t++-- | \(O(\min(n,W))\). Insert with a combining function.+-- @'insertWithKey' f key value mp@+-- will insert the pair (key, value) into @mp@ if key does+-- not exist in the map. If the key does exist, the function will+-- insert @f key new_value old_value@.+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > insertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]+-- > insertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]+-- > insertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"+--+-- If the key exists in the map, this function is lazy in @value@ but strict+-- in the result of @f@.++insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> Word64Map a -> Word64Map a+insertWithKey f !k x t =+  case t of+    Bin p m l r+      | nomatch k p m -> link k (singleton k x) p t+      | zero k m      -> Bin p m (insertWithKey f k x l) r+      | otherwise     -> Bin p m l (insertWithKey f k x r)+    Tip ky y+      | k==ky         -> Tip k $! f k x y+      | otherwise     -> link k (singleton k x) ky t+    Nil -> singleton k x++-- | \(O(\min(n,W))\). The expression (@'insertLookupWithKey' f k x map@)+-- is a pair where the first element is equal to (@'lookup' k map@)+-- and the second element equal to (@'insertWithKey' f k x map@).+--+-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value+-- > insertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])+-- > insertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])+-- > insertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")+--+-- This is how to define @insertLookup@ using @insertLookupWithKey@:+--+-- > let insertLookup kx x t = insertLookupWithKey (\_ a _ -> a) kx x t+-- > insertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])+-- > insertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])++insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> Word64Map a -> (Maybe a, Word64Map a)+insertLookupWithKey f0 !k0 x0 t0 = toPair $ go f0 k0 x0 t0+  where+    go f k x t =+      case t of+        Bin p m l r+          | nomatch k p m -> Nothing :*: link k (singleton k x) p t+          | zero k m      -> let (found :*: l') = go f k x l in (found :*: Bin p m l' r)+          | otherwise     -> let (found :*: r') = go f k x r in (found :*: Bin p m l r')+        Tip ky y+          | k==ky         -> (Just y :*: (Tip k $! f k x y))+          | otherwise     -> (Nothing :*: link k (singleton k x) ky t)+        Nil -> Nothing :*: (singleton k x)+++{--------------------------------------------------------------------+  Deletion+--------------------------------------------------------------------}+-- | \(O(\min(n,W))\). Adjust a value at a specific key. When the key is not+-- a member of the map, the original map is returned.+--+-- > adjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]+-- > adjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]+-- > adjust ("new " ++) 7 empty                         == empty++adjust ::  (a -> a) -> Key -> Word64Map a -> Word64Map a+adjust f k m+  = adjustWithKey (\_ x -> f x) k m++-- | \(O(\min(n,W))\). Adjust a value at a specific key. When the key is not+-- a member of the map, the original map is returned.+--+-- > let f key x = (show key) ++ ":new " ++ x+-- > adjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]+-- > adjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]+-- > adjustWithKey f 7 empty                         == empty++adjustWithKey ::  (Key -> a -> a) -> Key -> Word64Map a -> Word64Map a+adjustWithKey f !k t =+  case t of+    Bin p m l r+      | nomatch k p m -> t+      | zero k m      -> Bin p m (adjustWithKey f k l) r+      | otherwise     -> Bin p m l (adjustWithKey f k r)+    Tip ky y+      | k==ky         -> Tip ky $! f k y+      | otherwise     -> t+    Nil -> Nil++-- | \(O(\min(n,W))\). The expression (@'update' f k map@) updates the value @x@+-- at @k@ (if it is in the map). If (@f x@) is 'Nothing', the element is+-- deleted. If it is (@'Just' y@), the key @k@ is bound to the new value @y@.+--+-- > let f x = if x == "a" then Just "new a" else Nothing+-- > update f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]+-- > update f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]+-- > update f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"++update ::  (a -> Maybe a) -> Key -> Word64Map a -> Word64Map a+update f+  = updateWithKey (\_ x -> f x)++-- | \(O(\min(n,W))\). The expression (@'update' f k map@) updates the value @x@+-- at @k@ (if it is in the map). If (@f k x@) is 'Nothing', the element is+-- deleted. If it is (@'Just' y@), the key @k@ is bound to the new value @y@.+--+-- > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing+-- > updateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]+-- > updateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]+-- > updateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"++updateWithKey ::  (Key -> a -> Maybe a) -> Key -> Word64Map a -> Word64Map a+updateWithKey f !k t =+  case t of+    Bin p m l r+      | nomatch k p m -> t+      | zero k m      -> binCheckLeft p m (updateWithKey f k l) r+      | otherwise     -> binCheckRight p m l (updateWithKey f k r)+    Tip ky y+      | k==ky         -> case f k y of+                           Just !y' -> Tip ky y'+                           Nothing -> Nil+      | otherwise     -> t+    Nil -> Nil++-- | \(O(\min(n,W))\). Lookup and update.+-- The function returns original value, if it is updated.+-- This is different behavior than 'Data.Map.updateLookupWithKey'.+-- Returns the original key value if the map entry is deleted.+--+-- > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing+-- > updateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:new a")])+-- > updateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])+-- > updateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")++updateLookupWithKey ::  (Key -> a -> Maybe a) -> Key -> Word64Map a -> (Maybe a,Word64Map a)+updateLookupWithKey f0 !k0 t0 = toPair $ go f0 k0 t0+  where+    go f k t =+      case t of+        Bin p m l r+          | nomatch k p m -> (Nothing :*: t)+          | zero k m      -> let (found :*: l') = go f k l in (found :*: binCheckLeft p m l' r)+          | otherwise     -> let (found :*: r') = go f k r in (found :*: binCheckRight p m l r')+        Tip ky y+          | k==ky         -> case f k y of+                               Just !y' -> (Just y :*: Tip ky y')+                               Nothing  -> (Just y :*: Nil)+          | otherwise     -> (Nothing :*: t)+        Nil -> (Nothing :*: Nil)++++-- | \(O(\min(n,W))\). The expression (@'alter' f k map@) alters the value @x@ at @k@, or absence thereof.+-- 'alter' can be used to insert, delete, or update a value in an 'Word64Map'.+-- In short : @'lookup' k ('alter' f k m) = f ('lookup' k m)@.+alter :: (Maybe a -> Maybe a) -> Key -> Word64Map a -> Word64Map a+alter f !k t =+  case t of+    Bin p m l r+      | nomatch k p m -> case f Nothing of+                           Nothing -> t+                           Just !x  -> link k (Tip k x) p t+      | zero k m      -> binCheckLeft p m (alter f k l) r+      | otherwise     -> binCheckRight p m l (alter f k r)+    Tip ky y+      | k==ky         -> case f (Just y) of+                           Just !x -> Tip ky x+                           Nothing -> Nil+      | otherwise     -> case f Nothing of+                           Just !x -> link k (Tip k x) ky t+                           Nothing -> t+    Nil               -> case f Nothing of+                           Just !x -> Tip k x+                           Nothing -> Nil++-- | \(O(\log n)\). The expression (@'alterF' f k map@) alters the value @x@ at+-- @k@, or absence thereof.  'alterF' can be used to inspect, insert, delete,+-- or update a value in an 'Word64Map'.  In short : @'lookup' k <$> 'alterF' f k m = f+-- ('lookup' k m)@.+--+-- Example:+--+-- @+-- interactiveAlter :: Int -> Word64Map String -> IO (Word64Map String)+-- interactiveAlter k m = alterF f k m where+--   f Nothing = do+--      putStrLn $ show k +++--          " was not found in the map. Would you like to add it?"+--      getUserResponse1 :: IO (Maybe String)+--   f (Just old) = do+--      putStrLn $ "The key is currently bound to " ++ show old +++--          ". Would you like to change or delete it?"+--      getUserResponse2 :: IO (Maybe String)+-- @+--+-- 'alterF' is the most general operation for working with an individual+-- key that may or may not be in a given map.++-- Note: 'alterF' is a flipped version of the 'at' combinator from+-- 'Control.Lens.At'.+--+-- @since 0.5.8++alterF :: Functor f+       => (Maybe a -> f (Maybe a)) -> Key -> Word64Map a -> f (Word64Map a)+-- This implementation was modified from 'Control.Lens.At'.+alterF f k m = (<$> f mv) $ \fres ->+  case fres of+    Nothing -> maybe m (const (delete k m)) mv+    Just !v' -> insert k v' m+  where mv = lookup k m+++{--------------------------------------------------------------------+  Union+--------------------------------------------------------------------}+-- | The union of a list of maps, with a combining operation.+--+-- > unionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]+-- >     == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]++unionsWith :: Foldable f => (a->a->a) -> f (Word64Map a) -> Word64Map a+unionsWith f ts+  = Foldable.foldl' (unionWith f) empty ts++-- | \(O(n+m)\). The union with a combining function.+--+-- > unionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]++unionWith :: (a -> a -> a) -> Word64Map a -> Word64Map a -> Word64Map a+unionWith f m1 m2+  = unionWithKey (\_ x y -> f x y) m1 m2++-- | \(O(n+m)\). The union with a combining function.+--+-- > let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value+-- > unionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]++unionWithKey :: (Key -> a -> a -> a) -> Word64Map a -> Word64Map a -> Word64Map a+unionWithKey f m1 m2+  = mergeWithKey' Bin (\(Tip k1 x1) (Tip _k2 x2) -> Tip k1 $! f k1 x1 x2) id id m1 m2++{--------------------------------------------------------------------+  Difference+--------------------------------------------------------------------}++-- | \(O(n+m)\). Difference with a combining function.+--+-- > let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing+-- > differenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])+-- >     == singleton 3 "b:B"++differenceWith :: (a -> b -> Maybe a) -> Word64Map a -> Word64Map b -> Word64Map a+differenceWith f m1 m2+  = differenceWithKey (\_ x y -> f x y) m1 m2++-- | \(O(n+m)\). Difference with a combining function. When two equal keys are+-- encountered, the combining function is applied to the key and both values.+-- If it returns 'Nothing', the element is discarded (proper set difference).+-- If it returns (@'Just' y@), the element is updated with a new value @y@.+--+-- > let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing+-- > differenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])+-- >     == singleton 3 "3:b|B"++differenceWithKey :: (Key -> a -> b -> Maybe a) -> Word64Map a -> Word64Map b -> Word64Map a+differenceWithKey f m1 m2+  = mergeWithKey f id (const Nil) m1 m2++{--------------------------------------------------------------------+  Intersection+--------------------------------------------------------------------}++-- | \(O(n+m)\). The intersection with a combining function.+--+-- > intersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"++intersectionWith :: (a -> b -> c) -> Word64Map a -> Word64Map b -> Word64Map c+intersectionWith f m1 m2+  = intersectionWithKey (\_ x y -> f x y) m1 m2++-- | \(O(n+m)\). The intersection with a combining function.+--+-- > let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar+-- > intersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"++intersectionWithKey :: (Key -> a -> b -> c) -> Word64Map a -> Word64Map b -> Word64Map c+intersectionWithKey f m1 m2+  = mergeWithKey' bin (\(Tip k1 x1) (Tip _k2 x2) -> Tip k1 $! f k1 x1 x2) (const Nil) (const Nil) m1 m2++{--------------------------------------------------------------------+  MergeWithKey+--------------------------------------------------------------------}++-- | \(O(n+m)\). A high-performance universal combining function. Using+-- 'mergeWithKey', all combining functions can be defined without any loss of+-- efficiency (with exception of 'union', 'difference' and 'intersection',+-- where sharing of some nodes is lost with 'mergeWithKey').+--+-- Please make sure you know what is going on when using 'mergeWithKey',+-- otherwise you can be surprised by unexpected code growth or even+-- corruption of the data structure.+--+-- When 'mergeWithKey' is given three arguments, it is inlined to the call+-- site. You should therefore use 'mergeWithKey' only to define your custom+-- combining functions. For example, you could define 'unionWithKey',+-- 'differenceWithKey' and 'intersectionWithKey' as+--+-- > myUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -> Just (f k x1 x2)) id id m1 m2+-- > myDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2+-- > myIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -> Just (f k x1 x2)) (const empty) (const empty) m1 m2+--+-- When calling @'mergeWithKey' combine only1 only2@, a function combining two+-- 'Word64Map's is created, such that+--+-- * if a key is present in both maps, it is passed with both corresponding+--   values to the @combine@ function. Depending on the result, the key is either+--   present in the result with specified value, or is left out;+--+-- * a nonempty subtree present only in the first map is passed to @only1@ and+--   the output is added to the result;+--+-- * a nonempty subtree present only in the second map is passed to @only2@ and+--   the output is added to the result.+--+-- The @only1@ and @only2@ methods /must return a map with a subset (possibly empty) of the keys of the given map/.+-- The values can be modified arbitrarily.  Most common variants of @only1@ and+-- @only2@ are 'id' and @'const' 'empty'@, but for example @'map' f@ or+-- @'filterWithKey' f@ could be used for any @f@.++mergeWithKey :: (Key -> a -> b -> Maybe c) -> (Word64Map a -> Word64Map c) -> (Word64Map b -> Word64Map c)+             -> Word64Map a -> Word64Map b -> Word64Map c+mergeWithKey f g1 g2 = mergeWithKey' bin combine g1 g2+  where -- We use the lambda form to avoid non-exhaustive pattern matches warning.+        combine = \(Tip k1 x1) (Tip _k2 x2) -> case f k1 x1 x2 of Nothing -> Nil+                                                                  Just !x -> Tip k1 x+        {-# INLINE combine #-}+{-# INLINE mergeWithKey #-}++{--------------------------------------------------------------------+  Min\/Max+--------------------------------------------------------------------}++-- | \(O(\log n)\). Update the value at the minimal key.+--+-- > updateMinWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]+-- > updateMinWithKey (\ _ _ -> Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"++updateMinWithKey :: (Key -> a -> Maybe a) -> Word64Map a -> Word64Map a+updateMinWithKey f t =+  case t of Bin p m l r | m < 0 -> binCheckRight p m l (go f r)+            _ -> go f t+  where+    go f' (Bin p m l r) = binCheckLeft p m (go f' l) r+    go f' (Tip k y) = case f' k y of+                        Just !y' -> Tip k y'+                        Nothing -> Nil+    go _ Nil = error "updateMinWithKey Nil"++-- | \(O(\log n)\). Update the value at the maximal key.+--+-- > updateMaxWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]+-- > updateMaxWithKey (\ _ _ -> Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"++updateMaxWithKey :: (Key -> a -> Maybe a) -> Word64Map a -> Word64Map a+updateMaxWithKey f t =+  case t of Bin p m l r | m < 0 -> binCheckLeft p m (go f l) r+            _ -> go f t+  where+    go f' (Bin p m l r) = binCheckRight p m l (go f' r)+    go f' (Tip k y) = case f' k y of+                        Just !y' -> Tip k y'+                        Nothing -> Nil+    go _ Nil = error "updateMaxWithKey Nil"++-- | \(O(\log n)\). Update the value at the maximal key.+--+-- > updateMax (\ a -> Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]+-- > updateMax (\ _ -> Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"++updateMax :: (a -> Maybe a) -> Word64Map a -> Word64Map a+updateMax f = updateMaxWithKey (const f)++-- | \(O(\log n)\). Update the value at the minimal key.+--+-- > updateMin (\ a -> Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]+-- > updateMin (\ _ -> Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"++updateMin :: (a -> Maybe a) -> Word64Map a -> Word64Map a+updateMin f = updateMinWithKey (const f)+++{--------------------------------------------------------------------+  Mapping+--------------------------------------------------------------------}+-- | \(O(n)\). Map a function over all values in the map.+--+-- > map (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]++map :: (a -> b) -> Word64Map a -> Word64Map b+map f = go+  where+    go (Bin p m l r) = Bin p m (go l) (go r)+    go (Tip k x)     = Tip k $! f x+    go Nil           = Nil++#ifdef __GLASGOW_HASKELL__+{-# NOINLINE [1] map #-}+{-# RULES+"map/map" forall f g xs . map f (map g xs) = map (\x -> f $! g x) xs+"map/mapL" forall f g xs . map f (L.map g xs) = map (\x -> f (g x)) xs+ #-}+#endif++-- | \(O(n)\). Map a function over all values in the map.+--+-- > let f key x = (show key) ++ ":" ++ x+-- > mapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]++mapWithKey :: (Key -> a -> b) -> Word64Map a -> Word64Map b+mapWithKey f t+  = case t of+      Bin p m l r -> Bin p m (mapWithKey f l) (mapWithKey f r)+      Tip k x     -> Tip k $! f k x+      Nil         -> Nil++#ifdef __GLASGOW_HASKELL__+-- Pay close attention to strictness here. We need to force the+-- intermediate result for map f . map g, and we need to refrain+-- from forcing it for map f . L.map g, etc.+--+-- TODO Consider moving map and mapWithKey to Word64Map.Internal so we can write+-- non-orphan RULES for things like L.map f (map g xs). We'd need a new function+-- for this, and we'd have to pay attention to simplifier phases. Something like+--+-- lsmap :: (b -> c) -> (a -> b) -> Word64Map a -> Word64Map c+-- lsmap _ _ Nil = Nil+-- lsmap f g (Tip k x) = let !gx = g x in Tip k (f gx)+-- lsmap f g (Bin p m l r) = Bin p m (lsmap f g l) (lsmap f g r)+{-# NOINLINE [1] mapWithKey #-}+{-# RULES+"mapWithKey/mapWithKey" forall f g xs . mapWithKey f (mapWithKey g xs) =+  mapWithKey (\k a -> f k $! g k a) xs+"mapWithKey/mapWithKeyL" forall f g xs . mapWithKey f (L.mapWithKey g xs) =+  mapWithKey (\k a -> f k (g k a)) xs+"mapWithKey/map" forall f g xs . mapWithKey f (map g xs) =+  mapWithKey (\k a -> f k $! g a) xs+"mapWithKey/mapL" forall f g xs . mapWithKey f (L.map g xs) =+  mapWithKey (\k a -> f k (g a)) xs+"map/mapWithKey" forall f g xs . map f (mapWithKey g xs) =+  mapWithKey (\k a -> f $! g k a) xs+"map/mapWithKeyL" forall f g xs . map f (L.mapWithKey g xs) =+  mapWithKey (\k a -> f (g k a)) xs+ #-}+#endif++-- | \(O(n)\).+-- @'traverseWithKey' f s == 'fromList' <$> 'traverse' (\(k, v) -> (,) k <$> f k v) ('toList' m)@+-- That is, behaves exactly like a regular 'traverse' except that the traversing+-- function also has access to the key associated with a value.+--+-- > traverseWithKey (\k v -> if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])+-- > traverseWithKey (\k v -> if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing+traverseWithKey :: Applicative t => (Key -> a -> t b) -> Word64Map a -> t (Word64Map b)+traverseWithKey f = go+  where+    go Nil = pure Nil+    go (Tip k v) = (\ !v' -> Tip k v') <$> f k v+    go (Bin p m l r)+      | m < 0     = liftA2 (flip (Bin p m)) (go r) (go l)+      | otherwise = liftA2 (Bin p m) (go l) (go r)+{-# INLINE traverseWithKey #-}++-- | \(O(n)\). Traverse keys\/values and collect the 'Just' results.+--+-- @since 0.6.4+traverseMaybeWithKey+  :: Applicative f => (Key -> a -> f (Maybe b)) -> Word64Map a -> f (Word64Map b)+traverseMaybeWithKey f = go+    where+    go Nil           = pure Nil+    go (Tip k x)     = maybe Nil (Tip k $!) <$> f k x+    go (Bin p m l r)+      | m < 0     = liftA2 (flip (bin p m)) (go r) (go l)+      | otherwise = liftA2 (bin p m) (go l) (go r)++-- | \(O(n)\). The function @'mapAccum'@ threads an accumulating+-- argument through the map in ascending order of keys.+--+-- > let f a b = (a ++ b, b ++ "X")+-- > mapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])++mapAccum :: (a -> b -> (a,c)) -> a -> Word64Map b -> (a,Word64Map c)+mapAccum f = mapAccumWithKey (\a' _ x -> f a' x)++-- | \(O(n)\). The function @'mapAccumWithKey'@ threads an accumulating+-- argument through the map in ascending order of keys.+--+-- > let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")+-- > mapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])++mapAccumWithKey :: (a -> Key -> b -> (a,c)) -> a -> Word64Map b -> (a,Word64Map c)+mapAccumWithKey f a t+  = mapAccumL f a t++-- | \(O(n)\). The function @'mapAccumL'@ threads an accumulating+-- argument through the map in ascending order of keys.  Strict in+-- the accumulating argument and the both elements of the+-- result of the function.+mapAccumL :: (a -> Key -> b -> (a,c)) -> a -> Word64Map b -> (a,Word64Map c)+mapAccumL f0 a0 t0 = toPair $ go f0 a0 t0+  where+    go f a t+      = case t of+          Bin p m l r+            | m < 0 ->+                let (a1 :*: r') = go f a r+                    (a2 :*: l') = go f a1 l+                in (a2 :*: Bin p m l' r')+            | otherwise ->+                let (a1 :*: l') = go f a l+                    (a2 :*: r') = go f a1 r+                in (a2 :*: Bin p m l' r')+          Tip k x     -> let !(a',!x') = f a k x in (a' :*: Tip k x')+          Nil         -> (a :*: Nil)++-- | \(O(n)\). The function @'mapAccumRWithKey'@ threads an accumulating+-- argument through the map in descending order of keys.+mapAccumRWithKey :: (a -> Key -> b -> (a,c)) -> a -> Word64Map b -> (a,Word64Map c)+mapAccumRWithKey f0 a0 t0 = toPair $ go f0 a0 t0+  where+    go f a t+      = case t of+          Bin p m l r+            | m < 0 ->+              let (a1 :*: l') = go f a l+                  (a2 :*: r') = go f a1 r+              in (a2 :*: Bin p m l' r')+            | otherwise ->+              let (a1 :*: r') = go f a r+                  (a2 :*: l') = go f a1 l+              in (a2 :*: Bin p m l' r')+          Tip k x     -> let !(a',!x') = f a k x in (a' :*: Tip k x')+          Nil         -> (a :*: Nil)++-- | \(O(n \log n)\).+-- @'mapKeysWith' c f s@ is the map obtained by applying @f@ to each key of @s@.+--+-- The size of the result may be smaller if @f@ maps two or more distinct+-- keys to the same new key.  In this case the associated values will be+-- combined using @c@.+--+-- > mapKeysWith (++) (\ _ -> 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"+-- > mapKeysWith (++) (\ _ -> 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"++mapKeysWith :: (a -> a -> a) -> (Key->Key) -> Word64Map a -> Word64Map a+mapKeysWith c f = fromListWith c . foldrWithKey (\k x xs -> (f k, x) : xs) []++{--------------------------------------------------------------------+  Filter+--------------------------------------------------------------------}+-- | \(O(n)\). Map values and collect the 'Just' results.+--+-- > let f x = if x == "a" then Just "new a" else Nothing+-- > mapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"++mapMaybe :: (a -> Maybe b) -> Word64Map a -> Word64Map b+mapMaybe f = mapMaybeWithKey (\_ x -> f x)++-- | \(O(n)\). Map keys\/values and collect the 'Just' results.+--+-- > let f k _ = if k < 5 then Just ("key : " ++ (show k)) else Nothing+-- > mapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"++mapMaybeWithKey :: (Key -> a -> Maybe b) -> Word64Map a -> Word64Map b+mapMaybeWithKey f (Bin p m l r)+  = bin p m (mapMaybeWithKey f l) (mapMaybeWithKey f r)+mapMaybeWithKey f (Tip k x) = case f k x of+  Just !y  -> Tip k y+  Nothing -> Nil+mapMaybeWithKey _ Nil = Nil++-- | \(O(n)\). Map values and separate the 'Left' and 'Right' results.+--+-- > let f a = if a < "c" then Left a else Right a+-- > mapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])+-- >     == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])+-- >+-- > mapEither (\ a -> Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])+-- >     == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])++mapEither :: (a -> Either b c) -> Word64Map a -> (Word64Map b, Word64Map c)+mapEither f m+  = mapEitherWithKey (\_ x -> f x) m++-- | \(O(n)\). Map keys\/values and separate the 'Left' and 'Right' results.+--+-- > let f k a = if k < 5 then Left (k * 2) else Right (a ++ a)+-- > mapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])+-- >     == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])+-- >+-- > mapEitherWithKey (\_ a -> Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])+-- >     == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])++mapEitherWithKey :: (Key -> a -> Either b c) -> Word64Map a -> (Word64Map b, Word64Map c)+mapEitherWithKey f0 t0 = toPair $ go f0 t0+  where+    go f (Bin p m l r)+      = bin p m l1 r1 :*: bin p m l2 r2+      where+        (l1 :*: l2) = go f l+        (r1 :*: r2) = go f r+    go f (Tip k x) = case f k x of+      Left !y  -> (Tip k y :*: Nil)+      Right !z -> (Nil :*: Tip k z)+    go _ Nil = (Nil :*: Nil)++{--------------------------------------------------------------------+  Conversions+--------------------------------------------------------------------}++-- | \(O(n)\). Build a map from a set of keys and a function which for each key+-- computes its value.+--+-- > fromSet (\k -> replicate k 'a') (Data.Word64Set.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]+-- > fromSet undefined Data.Word64Set.empty == empty++fromSet :: (Key -> a) -> Word64Set.Word64Set -> Word64Map a+fromSet _ Word64Set.Nil = Nil+fromSet f (Word64Set.Bin p m l r) = Bin p m (fromSet f l) (fromSet f r)+fromSet f (Word64Set.Tip kx bm) = buildTree f kx bm (Word64Set.suffixBitMask + 1)+  where -- This is slightly complicated, as we to convert the dense+        -- representation of Word64Set into tree representation of Word64Map.+        --+        -- We are given a nonzero bit mask 'bmask' of 'bits' bits with prefix 'prefix'.+        -- We split bmask into halves corresponding to left and right subtree.+        -- If they are both nonempty, we create a Bin node, otherwise exactly+        -- one of them is nonempty and we construct the Word64Map from that half.+        buildTree g !prefix !bmask bits = case bits of+          0 -> Tip prefix $! g prefix+          _ -> case intFromNat ((natFromInt bits) `shiftRL` 1) of+                 bits2 | bmask .&. ((1 `shiftLL` fromIntegral bits2) - 1) == 0 ->+                           buildTree g (prefix + bits2) (bmask `shiftRL` fromIntegral bits2) bits2+                       | (bmask `shiftRL` fromIntegral bits2) .&. ((1 `shiftLL` fromIntegral bits2) - 1) == 0 ->+                           buildTree g prefix bmask bits2+                       | otherwise ->+                           Bin prefix bits2 (buildTree g prefix bmask bits2) (buildTree g (prefix + bits2) (bmask `shiftRL` fromIntegral bits2) bits2)++{--------------------------------------------------------------------+  Lists+--------------------------------------------------------------------}+-- | \(O(n \min(n,W))\). Create a map from a list of key\/value pairs.+--+-- > fromList [] == empty+-- > fromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]+-- > fromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]++fromList :: [(Key,a)] -> Word64Map a+fromList xs+  = Foldable.foldl' ins empty xs+  where+    ins t (k,x)  = insert k x t++-- | \(O(n \min(n,W))\). Create a map from a list of key\/value pairs with a combining function. See also 'fromAscListWith'.+--+-- > fromListWith (++) [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")] == fromList [(3, "ab"), (5, "aba")]+-- > fromListWith (++) [] == empty++fromListWith :: (a -> a -> a) -> [(Key,a)] -> Word64Map a+fromListWith f xs+  = fromListWithKey (\_ x y -> f x y) xs++-- | \(O(n \min(n,W))\). Build a map from a list of key\/value pairs with a combining function. See also fromAscListWithKey'.+--+-- > let f key new_value old_value = show key ++ ":" ++ new_value ++ "|" ++ old_value+-- > fromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "3:a|b"), (5, "5:c|5:b|a")]+-- > fromListWithKey f [] == empty++fromListWithKey :: (Key -> a -> a -> a) -> [(Key,a)] -> Word64Map a+fromListWithKey f xs+  = Foldable.foldl' ins empty xs+  where+    ins t (k,x) = insertWithKey f k x t++-- | \(O(n)\). Build a map from a list of key\/value pairs where+-- the keys are in ascending order.+--+-- > fromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]+-- > fromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]++fromAscList :: [(Key,a)] -> Word64Map a+fromAscList = fromMonoListWithKey Nondistinct (\_ x _ -> x)+{-# NOINLINE fromAscList #-}++-- | \(O(n)\). Build a map from a list of key\/value pairs where+-- the keys are in ascending order, with a combining function on equal keys.+-- /The precondition (input list is ascending) is not checked./+--+-- > fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]++fromAscListWith :: (a -> a -> a) -> [(Key,a)] -> Word64Map a+fromAscListWith f = fromMonoListWithKey Nondistinct (\_ x y -> f x y)+{-# NOINLINE fromAscListWith #-}++-- | \(O(n)\). Build a map from a list of key\/value pairs where+-- the keys are in ascending order, with a combining function on equal keys.+-- /The precondition (input list is ascending) is not checked./+--+-- > fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]++fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key,a)] -> Word64Map a+fromAscListWithKey f = fromMonoListWithKey Nondistinct f+{-# NOINLINE fromAscListWithKey #-}++-- | \(O(n)\). Build a map from a list of key\/value pairs where+-- the keys are in ascending order and all distinct.+-- /The precondition (input list is strictly ascending) is not checked./+--+-- > fromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]++fromDistinctAscList :: [(Key,a)] -> Word64Map a+fromDistinctAscList = fromMonoListWithKey Distinct (\_ x _ -> x)+{-# NOINLINE fromDistinctAscList #-}++-- | \(O(n)\). Build a map from a list of key\/value pairs with monotonic keys+-- and a combining function.+--+-- The precise conditions under which this function works are subtle:+-- For any branch mask, keys with the same prefix w.r.t. the branch+-- mask must occur consecutively in the list.++fromMonoListWithKey :: Distinct -> (Key -> a -> a -> a) -> [(Key,a)] -> Word64Map a+fromMonoListWithKey distinct f = go+  where+    go []              = Nil+    go ((kx,vx) : zs1) = addAll' kx vx zs1++    -- `addAll'` collects all keys equal to `kx` into a single value,+    -- and then proceeds with `addAll`.+    addAll' !kx vx []+        = Tip kx $! vx+    addAll' !kx vx ((ky,vy) : zs)+        | Nondistinct <- distinct, kx == ky+        = let !v = f kx vy vx in addAll' ky v zs+        -- inlined: | otherwise = addAll kx (Tip kx $! vx) (ky : zs)+        | m <- branchMask kx ky+        , Inserted ty zs' <- addMany' m ky vy zs+        = addAll kx (linkWithMask m ky ty {-kx-} (Tip kx $! vx)) zs'++    -- for `addAll` and `addMany`, kx is /a/ key inside the tree `tx`+    -- `addAll` consumes the rest of the list, adding to the tree `tx`+    addAll !_kx !tx []+        = tx+    addAll !kx !tx ((ky,vy) : zs)+        | m <- branchMask kx ky+        , Inserted ty zs' <- addMany' m ky vy zs+        = addAll kx (linkWithMask m ky ty {-kx-} tx) zs'++    -- `addMany'` is similar to `addAll'`, but proceeds with `addMany'`.+    addMany' !_m !kx vx []+        = Inserted (Tip kx $! vx) []+    addMany' !m !kx vx zs0@((ky,vy) : zs)+        | Nondistinct <- distinct, kx == ky+        = let !v = f kx vy vx in addMany' m ky v zs+        -- inlined: | otherwise = addMany m kx (Tip kx $! vx) (ky : zs)+        | mask kx m /= mask ky m+        = Inserted (Tip kx $! vx) zs0+        | mxy <- branchMask kx ky+        , Inserted ty zs' <- addMany' mxy ky vy zs+        = addMany m kx (linkWithMask mxy ky ty {-kx-} (Tip kx $! vx)) zs'++    -- `addAll` adds to `tx` all keys whose prefix w.r.t. `m` agrees with `kx`.+    addMany !_m !_kx tx []+        = Inserted tx []+    addMany !m !kx tx zs0@((ky,vy) : zs)+        | mask kx m /= mask ky m+        = Inserted tx zs0+        | mxy <- branchMask kx ky+        , Inserted ty zs' <- addMany' mxy ky vy zs+        = addMany m kx (linkWithMask mxy ky ty {-kx-} tx) zs'+{-# INLINE fromMonoListWithKey #-}++data Inserted a = Inserted !(Word64Map a) ![(Key,a)]++data Distinct = Distinct | Nondistinct
+ GHC/Data/Word64Set.hs view
@@ -0,0 +1,174 @@+{-# LANGUAGE CPP #-}+#if !defined(TESTING) && defined(__GLASGOW_HASKELL__)+{-# LANGUAGE Safe #-}+#endif++#include "containers.h"++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Word64Set+-- Copyright   :  (c) Daan Leijen 2002+--                (c) Joachim Breitner 2011+-- License     :  BSD-style+-- Maintainer  :  libraries@haskell.org+-- Portability :  portable+--+--+-- = Finite Int Sets+--+-- The @'Word64Set'@ type represents a set of elements of type @Int@.+--+-- For a walkthrough of the most commonly used functions see their+-- <https://haskell-containers.readthedocs.io/en/latest/set.html sets introduction>.+--+-- These modules are intended to be imported qualified, to avoid name+-- clashes with Prelude functions, e.g.+--+-- >  import Data.Word64Set (Word64Set)+-- >  import qualified Data.Word64Set as Word64Set+--+--+-- == Performance information+--+-- Many operations have a worst-case complexity of \(O(\min(n,W))\).+-- This means that the operation can become linear in the number of+-- elements with a maximum of \(W\) -- the number of bits in an 'Int'+-- (32 or 64).+--+--+-- == Implementation+--+-- The implementation is based on /big-endian patricia trees/.  This data+-- structure performs especially well on binary operations like 'union'+-- and 'intersection'.  However, my benchmarks show that it is also+-- (much) faster on insertions and deletions when compared to a generic+-- size-balanced set implementation (see "Data.Set").+--+--    * Chris Okasaki and Andy Gill,  \"/Fast Mergeable Integer Maps/\",+--      Workshop on ML, September 1998, pages 77-86,+--      <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.37.5452>+--+--    * D.R. Morrison, \"/PATRICIA -- Practical Algorithm To Retrieve Information Coded In Alphanumeric/\",+--      Journal of the ACM, 15(4), October 1968, pages 514-534.+--+-- Additionally, this implementation places bitmaps in the leaves of the tree.+-- Their size is the natural size of a machine word (32 or 64 bits) and greatly+-- reduces the memory footprint and execution times for dense sets, e.g. sets+-- where it is likely that many values lie close to each other. The asymptotics+-- are not affected by this optimization.+--+-----------------------------------------------------------------------------++module GHC.Data.Word64Set (+            -- * Strictness properties+            -- $strictness++            -- * Set type+#if !defined(TESTING)+              Word64Set          -- instance Eq,Show+#else+              Word64Set(..)      -- instance Eq,Show+#endif+            , Key++            -- * Construction+            , empty+            , singleton+            , fromList+            , fromAscList+            , fromDistinctAscList++            -- * Insertion+            , insert++            -- * Deletion+            , delete++            -- * Generalized insertion/deletion+            , alterF++            -- * Query+            , member+            , notMember+            , lookupLT+            , lookupGT+            , lookupLE+            , lookupGE+            , WS.null+            , size+            , isSubsetOf+            , isProperSubsetOf+            , disjoint++            -- * Combine+            , union+            , unions+            , difference+            , (\\)+            , intersection++            -- * Filter+            , WS.filter+            , partition++            , takeWhileAntitone+            , dropWhileAntitone+            , spanAntitone++            , split+            , splitMember+            , splitRoot++            -- * Map+            , WS.map+            , mapMonotonic++            -- * Folds+            , WS.foldr+            , WS.foldl+            -- ** Strict folds+            , foldr'+            , foldl'+            -- ** Legacy folds+            , fold++            -- * Min\/Max+            , findMin+            , findMax+            , deleteMin+            , deleteMax+            , deleteFindMin+            , deleteFindMax+            , maxView+            , minView++            -- * Conversion++            -- ** List+            , elems+            , toList+            , toAscList+            , toDescList++            -- * Debugging+            , showTree+            , showTreeWith++#if defined(TESTING)+            -- * Internals+            , match+#endif+            ) where++import GHC.Data.Word64Set.Internal as WS++-- $strictness+--+-- This module satisfies the following strictness property:+--+-- * Key arguments are evaluated to WHNF+--+-- Here are some examples that illustrate the property:+--+-- > delete undefined s  ==  undefined
+ GHC/Data/Word64Set/Internal.hs view
@@ -0,0 +1,1704 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE PatternGuards #-}+#ifdef __GLASGOW_HASKELL__+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeFamilies #-}+#endif+#if !defined(TESTING) && defined(__GLASGOW_HASKELL__)+{-# LANGUAGE Trustworthy #-}+#endif++{-# OPTIONS_HADDOCK not-home #-}++#include "containers.h"++-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Word64Set.Internal+-- Copyright   :  (c) Daan Leijen 2002+--                (c) Joachim Breitner 2011+-- License     :  BSD-style+-- Maintainer  :  libraries@haskell.org+-- Portability :  portable+--+-- = WARNING+--+-- This module is considered __internal__.+--+-- The Package Versioning Policy __does not apply__.+--+-- The contents of this module may change __in any way whatsoever__+-- and __without any warning__ between minor versions of this package.+--+-- Authors importing this module are expected to track development+-- closely.+--+-- = Description+--+-- An efficient implementation of integer sets.+--+-- These modules are intended to be imported qualified, to avoid name+-- clashes with Prelude functions, e.g.+--+-- >  import Data.Word64Set (Word64Set)+-- >  import qualified Data.Word64Set as Word64Set+--+-- The implementation is based on /big-endian patricia trees/.  This data+-- structure performs especially well on binary operations like 'union'+-- and 'intersection'.  However, my benchmarks show that it is also+-- (much) faster on insertions and deletions when compared to a generic+-- size-balanced set implementation (see "Data.Set").+--+--    * Chris Okasaki and Andy Gill,  \"/Fast Mergeable Integer Maps/\",+--      Workshop on ML, September 1998, pages 77-86,+--      <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.37.5452>+--+--    * D.R. Morrison, \"/PATRICIA -- Practical Algorithm To Retrieve Information Coded In Alphanumeric/\",+--      Journal of the ACM, 15(4), October 1968, pages 514-534.+--+-- Additionally, this implementation places bitmaps in the leaves of the tree.+-- Their size is the natural size of a machine word (32 or 64 bits) and greatly+-- reduce memory footprint and execution times for dense sets, e.g. sets where+-- it is likely that many values lie close to each other. The asymptotics are+-- not affected by this optimization.+--+-- Many operations have a worst-case complexity of \(O(\min(n,W))\).+-- This means that the operation can become linear in the number of+-- elements with a maximum of \(W\) -- the number of bits in an 'Int'+-- (32 or 64).+--+-- @since 0.5.9+-----------------------------------------------------------------------------++-- [Note: INLINE bit fiddling]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- It is essential that the bit fiddling functions like mask, zero, branchMask+-- etc are inlined. If they do not, the memory allocation skyrockets. The GHC+-- usually gets it right, but it is disastrous if it does not. Therefore we+-- explicitly mark these functions INLINE.+++-- [Note: Local 'go' functions and capturing]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- Care must be taken when using 'go' function which captures an argument.+-- Sometimes (for example when the argument is passed to a data constructor,+-- as in insert), GHC heap-allocates more than necessary. Therefore C-- code+-- must be checked for increased allocation when creating and modifying such+-- functions.+++-- [Note: Order of constructors]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- The order of constructors of Word64Set matters when considering performance.+-- Currently in GHC 7.0, when type has 3 constructors, they are matched from+-- the first to the last -- the best performance is achieved when the+-- constructors are ordered by frequency.+-- On GHC 7.0, reordering constructors from Nil | Tip | Bin to Bin | Tip | Nil+-- improves the benchmark by circa 10%.++module GHC.Data.Word64Set.Internal (+    -- * Set type+      Word64Set(..), Key -- instance Eq,Show+    , Prefix, Mask, BitMap++    -- * Operators+    , (\\)++    -- * Query+    , null+    , size+    , member+    , notMember+    , lookupLT+    , lookupGT+    , lookupLE+    , lookupGE+    , isSubsetOf+    , isProperSubsetOf+    , disjoint++    -- * Construction+    , empty+    , singleton+    , insert+    , delete+    , alterF++    -- * Combine+    , union+    , unions+    , difference+    , intersection++    -- * Filter+    , filter+    , partition++    , takeWhileAntitone+    , dropWhileAntitone+    , spanAntitone++    , split+    , splitMember+    , splitRoot++    -- * Map+    , map+    , mapMonotonic++    -- * Folds+    , foldr+    , foldl+    -- ** Strict folds+    , foldr'+    , foldl'+    -- ** Legacy folds+    , fold++    -- * Min\/Max+    , findMin+    , findMax+    , deleteMin+    , deleteMax+    , deleteFindMin+    , deleteFindMax+    , maxView+    , minView++    -- * Conversion++    -- ** List+    , elems+    , toList+    , fromList++    -- ** Ordered list+    , toAscList+    , toDescList+    , fromAscList+    , fromDistinctAscList++    -- * Debugging+    , showTree+    , showTreeWith++    -- * Internals+    , match+    , suffixBitMask+    , prefixBitMask+    , bitmapOf+    , zero+    ) where++import Control.Applicative (Const(..))+import Control.DeepSeq (NFData(rnf))+import Data.Bits+import qualified Data.List as List+import Data.Maybe (fromMaybe)+import Data.Semigroup (Semigroup(stimes, (<>)), stimesIdempotentMonoid)+import GHC.Prelude.Basic hiding+  (filter, foldr, foldl, foldl', null, map)+import Data.Word ( Word64 )++import GHC.Utils.Containers.Internal.BitUtil+import GHC.Utils.Containers.Internal.StrictPair++#if __GLASGOW_HASKELL__+import Data.Data (Data(..), Constr, mkConstr, constrIndex, DataType, mkDataType)+import qualified Data.Data+import Text.Read+#endif++#if __GLASGOW_HASKELL__+import qualified GHC.Exts+#endif++import qualified Data.Foldable as Foldable+import Data.Functor.Identity (Identity(..))++infixl 9 \\{-This comment teaches CPP correct behaviour -}++-- A "Nat" is a 64 bit machine word+type Nat = Word64++natFromInt :: Word64 -> Nat+natFromInt = id+{-# INLINE natFromInt #-}++intFromNat :: Nat -> Word64+intFromNat = id+{-# INLINE intFromNat #-}++{--------------------------------------------------------------------+  Operators+--------------------------------------------------------------------}+-- | \(O(n+m)\). See 'difference'.+(\\) :: Word64Set -> Word64Set -> Word64Set+m1 \\ m2 = difference m1 m2++{--------------------------------------------------------------------+  Types+--------------------------------------------------------------------}++-- | A set of integers.++-- See Note: Order of constructors+data Word64Set = Bin {-# UNPACK #-} !Prefix {-# UNPACK #-} !Mask !Word64Set !Word64Set+-- Invariant: Nil is never found as a child of Bin.+-- Invariant: The Mask is a power of 2.  It is the largest bit position at which+--            two elements of the set differ.+-- Invariant: Prefix is the common high-order bits that all elements share to+--            the left of the Mask bit.+-- Invariant: In Bin prefix mask left right, left consists of the elements that+--            don't have the mask bit set; right is all the elements that do.+            | Tip {-# UNPACK #-} !Prefix {-# UNPACK #-} !BitMap+-- Invariant: The Prefix is zero for the last 6 bits. The values of the set+--            represented by a tip are the prefix plus the indices of the set+--            bits in the bit map.+            | Nil++-- A number stored in a set is stored as+-- * Prefix (all but last 6 bits) and+-- * BitMap (last 6 bits stored as a bitmask)+--   Last 6 bits are called a Suffix.++type Prefix = Word64+type Mask   = Word64+type BitMap = Word64+type Key    = Word64++instance Monoid Word64Set where+    mempty  = empty+    mconcat = unions+    mappend = (<>)++-- | @since 0.5.7+instance Semigroup Word64Set where+    (<>)    = union+    stimes  = stimesIdempotentMonoid++#if __GLASGOW_HASKELL__++{--------------------------------------------------------------------+  A Data instance+--------------------------------------------------------------------}++-- This instance preserves data abstraction at the cost of inefficiency.+-- We provide limited reflection services for the sake of data abstraction.++instance Data Word64Set where+  gfoldl f z is = z fromList `f` (toList is)+  toConstr _     = fromListConstr+  gunfold k z c  = case constrIndex c of+    1 -> k (z fromList)+    _ -> error "gunfold"+  dataTypeOf _   = intSetDataType++fromListConstr :: Constr+fromListConstr = mkConstr intSetDataType "fromList" [] Data.Data.Prefix++intSetDataType :: DataType+intSetDataType = mkDataType "Data.Word64Set.Internal.Word64Set" [fromListConstr]++#endif++{--------------------------------------------------------------------+  Query+--------------------------------------------------------------------}+-- | \(O(1)\). Is the set empty?+null :: Word64Set -> Bool+null Nil = True+null _   = False+{-# INLINE null #-}++-- | \(O(n)\). Cardinality of the set.+size :: Word64Set -> Int+size = go 0+  where+    go !acc (Bin _ _ l r) = go (go acc l) r+    go acc (Tip _ bm) = acc + bitcount 0 bm+    go acc Nil = acc++-- | \(O(\min(n,W))\). Is the value a member of the set?++-- See Note: Local 'go' functions and capturing.+member :: Key -> Word64Set -> Bool+member !x = go+  where+    go (Bin p m l r)+      | nomatch x p m = False+      | zero x m      = go l+      | otherwise     = go r+    go (Tip y bm) = prefixOf x == y && bitmapOf x .&. bm /= 0+    go Nil = False++-- | \(O(\min(n,W))\). Is the element not in the set?+notMember :: Key -> Word64Set -> Bool+notMember k = not . member k++-- | \(O(\min(n,W))\). Find largest element smaller than the given one.+--+-- > lookupLT 3 (fromList [3, 5]) == Nothing+-- > lookupLT 5 (fromList [3, 5]) == Just 3++-- See Note: Local 'go' functions and capturing.+lookupLT :: Key -> Word64Set -> Maybe Key+lookupLT !x t = case t of+    Bin _ m l r | m < 0 -> if x >= 0 then go r l else go Nil r+    _ -> go Nil t+  where+    go def (Bin p m l r) | nomatch x p m = if x < p then unsafeFindMax def else unsafeFindMax r+                         | zero x m  = go def l+                         | otherwise = go l r+    go def (Tip kx bm) | prefixOf x > kx = Just $ kx + highestBitSet bm+                       | prefixOf x == kx && maskLT /= 0 = Just $ kx + highestBitSet maskLT+                       | otherwise = unsafeFindMax def+                       where maskLT = (bitmapOf x - 1) .&. bm+    go def Nil = unsafeFindMax def+++-- | \(O(\min(n,W))\). Find smallest element greater than the given one.+--+-- > lookupGT 4 (fromList [3, 5]) == Just 5+-- > lookupGT 5 (fromList [3, 5]) == Nothing++-- See Note: Local 'go' functions and capturing.+lookupGT :: Key -> Word64Set -> Maybe Key+lookupGT !x t = case t of+    Bin _ m l r | m < 0 -> if x >= 0 then go Nil l else go l r+    _ -> go Nil t+  where+    go def (Bin p m l r) | nomatch x p m = if x < p then unsafeFindMin l else unsafeFindMin def+                         | zero x m  = go r l+                         | otherwise = go def r+    go def (Tip kx bm) | prefixOf x < kx = Just $ kx + lowestBitSet bm+                       | prefixOf x == kx && maskGT /= 0 = Just $ kx + lowestBitSet maskGT+                       | otherwise = unsafeFindMin def+                       where maskGT = (- ((bitmapOf x) `shiftLL` 1)) .&. bm+    go def Nil = unsafeFindMin def+++-- | \(O(\min(n,W))\). Find largest element smaller or equal to the given one.+--+-- > lookupLE 2 (fromList [3, 5]) == Nothing+-- > lookupLE 4 (fromList [3, 5]) == Just 3+-- > lookupLE 5 (fromList [3, 5]) == Just 5++-- See Note: Local 'go' functions and capturing.+lookupLE :: Key -> Word64Set -> Maybe Key+lookupLE !x t = case t of+    Bin _ m l r | m < 0 -> if x >= 0 then go r l else go Nil r+    _ -> go Nil t+  where+    go def (Bin p m l r) | nomatch x p m = if x < p then unsafeFindMax def else unsafeFindMax r+                         | zero x m  = go def l+                         | otherwise = go l r+    go def (Tip kx bm) | prefixOf x > kx = Just $ kx + highestBitSet bm+                       | prefixOf x == kx && maskLE /= 0 = Just $ kx + highestBitSet maskLE+                       | otherwise = unsafeFindMax def+                       where maskLE = (((bitmapOf x) `shiftLL` 1) - 1) .&. bm+    go def Nil = unsafeFindMax def+++-- | \(O(\min(n,W))\). Find smallest element greater or equal to the given one.+--+-- > lookupGE 3 (fromList [3, 5]) == Just 3+-- > lookupGE 4 (fromList [3, 5]) == Just 5+-- > lookupGE 6 (fromList [3, 5]) == Nothing++-- See Note: Local 'go' functions and capturing.+lookupGE :: Key -> Word64Set -> Maybe Key+lookupGE !x t = case t of+    Bin _ m l r | m < 0 -> if x >= 0 then go Nil l else go l r+    _ -> go Nil t+  where+    go def (Bin p m l r) | nomatch x p m = if x < p then unsafeFindMin l else unsafeFindMin def+                         | zero x m  = go r l+                         | otherwise = go def r+    go def (Tip kx bm) | prefixOf x < kx = Just $ kx + lowestBitSet bm+                       | prefixOf x == kx && maskGE /= 0 = Just $ kx + lowestBitSet maskGE+                       | otherwise = unsafeFindMin def+                       where maskGE = (- (bitmapOf x)) .&. bm+    go def Nil = unsafeFindMin def++++-- Helper function for lookupGE and lookupGT. It assumes that if a Bin node is+-- given, it has m > 0.+unsafeFindMin :: Word64Set -> Maybe Key+unsafeFindMin Nil = Nothing+unsafeFindMin (Tip kx bm) = Just $ kx + lowestBitSet bm+unsafeFindMin (Bin _ _ l _) = unsafeFindMin l++-- Helper function for lookupLE and lookupLT. It assumes that if a Bin node is+-- given, it has m > 0.+unsafeFindMax :: Word64Set -> Maybe Key+unsafeFindMax Nil = Nothing+unsafeFindMax (Tip kx bm) = Just $ kx + highestBitSet bm+unsafeFindMax (Bin _ _ _ r) = unsafeFindMax r++{--------------------------------------------------------------------+  Construction+--------------------------------------------------------------------}+-- | \(O(1)\). The empty set.+empty :: Word64Set+empty+  = Nil+{-# INLINE empty #-}++-- | \(O(1)\). A set of one element.+singleton :: Key -> Word64Set+singleton x+  = Tip (prefixOf x) (bitmapOf x)+{-# INLINE singleton #-}++{--------------------------------------------------------------------+  Insert+--------------------------------------------------------------------}+-- | \(O(\min(n,W))\). Add a value to the set. There is no left- or right bias for+-- Word64Sets.+insert :: Key -> Word64Set -> Word64Set+insert !x = insertBM (prefixOf x) (bitmapOf x)++-- Helper function for insert and union.+insertBM :: Prefix -> BitMap -> Word64Set -> Word64Set+insertBM !kx !bm t@(Bin p m l r)+  | nomatch kx p m = link kx (Tip kx bm) p t+  | zero kx m      = Bin p m (insertBM kx bm l) r+  | otherwise      = Bin p m l (insertBM kx bm r)+insertBM kx bm t@(Tip kx' bm')+  | kx' == kx = Tip kx' (bm .|. bm')+  | otherwise = link kx (Tip kx bm) kx' t+insertBM kx bm Nil = Tip kx bm++-- | \(O(\min(n,W))\). Delete a value in the set. Returns the+-- original set when the value was not present.+delete :: Key -> Word64Set -> Word64Set+delete !x = deleteBM (prefixOf x) (bitmapOf x)++-- Deletes all values mentioned in the BitMap from the set.+-- Helper function for delete and difference.+deleteBM :: Prefix -> BitMap -> Word64Set -> Word64Set+deleteBM !kx !bm t@(Bin p m l r)+  | nomatch kx p m = t+  | zero kx m      = bin p m (deleteBM kx bm l) r+  | otherwise      = bin p m l (deleteBM kx bm r)+deleteBM kx bm t@(Tip kx' bm')+  | kx' == kx = tip kx (bm' .&. complement bm)+  | otherwise = t+deleteBM _ _ Nil = Nil++-- | \(O(\min(n,W))\). @('alterF' f x s)@ can delete or insert @x@ in @s@ depending+-- on whether it is already present in @s@.+--+-- In short:+--+-- @+-- 'member' x \<$\> 'alterF' f x s = f ('member' x s)+-- @+--+-- Note: 'alterF' is a variant of the @at@ combinator from "Control.Lens.At".+--+-- @since 0.6.3.1+alterF :: Functor f => (Bool -> f Bool) -> Key -> Word64Set -> f Word64Set+alterF f k s = fmap choose (f member_)+  where+    member_ = member k s++    (inserted, deleted)+      | member_   = (s         , delete k s)+      | otherwise = (insert k s, s         )++    choose True  = inserted+    choose False = deleted+#ifndef __GLASGOW_HASKELL__+{-# INLINE alterF #-}+#else+{-# INLINABLE [2] alterF #-}++{-# RULES+"alterF/Const" forall k (f :: Bool -> Const a Bool) . alterF f k = \s -> Const . getConst . f $ member k s+ #-}+#endif++{-# SPECIALIZE alterF :: (Bool -> Identity Bool) -> Key -> Word64Set -> Identity Word64Set #-}++{--------------------------------------------------------------------+  Union+--------------------------------------------------------------------}+-- | The union of a list of sets.+unions :: Foldable f => f Word64Set -> Word64Set+unions xs+  = Foldable.foldl' union empty xs+++-- | \(O(n+m)\). The union of two sets.+union :: Word64Set -> Word64Set -> Word64Set+union t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)+  | shorter m1 m2  = union1+  | shorter m2 m1  = union2+  | p1 == p2       = Bin p1 m1 (union l1 l2) (union r1 r2)+  | otherwise      = link p1 t1 p2 t2+  where+    union1  | nomatch p2 p1 m1  = link p1 t1 p2 t2+            | zero p2 m1        = Bin p1 m1 (union l1 t2) r1+            | otherwise         = Bin p1 m1 l1 (union r1 t2)++    union2  | nomatch p1 p2 m2  = link p1 t1 p2 t2+            | zero p1 m2        = Bin p2 m2 (union t1 l2) r2+            | otherwise         = Bin p2 m2 l2 (union t1 r2)++union t@(Bin _ _ _ _) (Tip kx bm) = insertBM kx bm t+union t@(Bin _ _ _ _) Nil = t+union (Tip kx bm) t = insertBM kx bm t+union Nil t = t+++{--------------------------------------------------------------------+  Difference+--------------------------------------------------------------------}+-- | \(O(n+m)\). Difference between two sets.+difference :: Word64Set -> Word64Set -> Word64Set+difference t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)+  | shorter m1 m2  = difference1+  | shorter m2 m1  = difference2+  | p1 == p2       = bin p1 m1 (difference l1 l2) (difference r1 r2)+  | otherwise      = t1+  where+    difference1 | nomatch p2 p1 m1  = t1+                | zero p2 m1        = bin p1 m1 (difference l1 t2) r1+                | otherwise         = bin p1 m1 l1 (difference r1 t2)++    difference2 | nomatch p1 p2 m2  = t1+                | zero p1 m2        = difference t1 l2+                | otherwise         = difference t1 r2++difference t@(Bin _ _ _ _) (Tip kx bm) = deleteBM kx bm t+difference t@(Bin _ _ _ _) Nil = t++difference t1@(Tip kx bm) t2 = differenceTip t2+  where differenceTip (Bin p2 m2 l2 r2) | nomatch kx p2 m2 = t1+                                        | zero kx m2 = differenceTip l2+                                        | otherwise = differenceTip r2+        differenceTip (Tip kx2 bm2) | kx == kx2 = tip kx (bm .&. complement bm2)+                                    | otherwise = t1+        differenceTip Nil = t1++difference Nil _     = Nil++++{--------------------------------------------------------------------+  Intersection+--------------------------------------------------------------------}+-- | \(O(n+m)\). The intersection of two sets.+intersection :: Word64Set -> Word64Set -> Word64Set+intersection t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)+  | shorter m1 m2  = intersection1+  | shorter m2 m1  = intersection2+  | p1 == p2       = bin p1 m1 (intersection l1 l2) (intersection r1 r2)+  | otherwise      = Nil+  where+    intersection1 | nomatch p2 p1 m1  = Nil+                  | zero p2 m1        = intersection l1 t2+                  | otherwise         = intersection r1 t2++    intersection2 | nomatch p1 p2 m2  = Nil+                  | zero p1 m2        = intersection t1 l2+                  | otherwise         = intersection t1 r2++intersection t1@(Bin _ _ _ _) (Tip kx2 bm2) = intersectBM t1+  where intersectBM (Bin p1 m1 l1 r1) | nomatch kx2 p1 m1 = Nil+                                      | zero kx2 m1       = intersectBM l1+                                      | otherwise         = intersectBM r1+        intersectBM (Tip kx1 bm1) | kx1 == kx2 = tip kx1 (bm1 .&. bm2)+                                  | otherwise = Nil+        intersectBM Nil = Nil++intersection (Bin _ _ _ _) Nil = Nil++intersection (Tip kx1 bm1) t2 = intersectBM t2+  where intersectBM (Bin p2 m2 l2 r2) | nomatch kx1 p2 m2 = Nil+                                      | zero kx1 m2       = intersectBM l2+                                      | otherwise         = intersectBM r2+        intersectBM (Tip kx2 bm2) | kx1 == kx2 = tip kx1 (bm1 .&. bm2)+                                  | otherwise = Nil+        intersectBM Nil = Nil++intersection Nil _ = Nil++{--------------------------------------------------------------------+  Subset+--------------------------------------------------------------------}+-- | \(O(n+m)\). Is this a proper subset? (ie. a subset but not equal).+isProperSubsetOf :: Word64Set -> Word64Set -> Bool+isProperSubsetOf t1 t2+  = case subsetCmp t1 t2 of+      LT -> True+      _  -> False++subsetCmp :: Word64Set -> Word64Set -> Ordering+subsetCmp t1@(Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)+  | shorter m1 m2  = GT+  | shorter m2 m1  = case subsetCmpLt of+                       GT -> GT+                       _  -> LT+  | p1 == p2       = subsetCmpEq+  | otherwise      = GT  -- disjoint+  where+    subsetCmpLt | nomatch p1 p2 m2  = GT+                | zero p1 m2        = subsetCmp t1 l2+                | otherwise         = subsetCmp t1 r2+    subsetCmpEq = case (subsetCmp l1 l2, subsetCmp r1 r2) of+                    (GT,_ ) -> GT+                    (_ ,GT) -> GT+                    (EQ,EQ) -> EQ+                    _       -> LT++subsetCmp (Bin _ _ _ _) _  = GT+subsetCmp (Tip kx1 bm1) (Tip kx2 bm2)+  | kx1 /= kx2                  = GT -- disjoint+  | bm1 == bm2                  = EQ+  | bm1 .&. complement bm2 == 0 = LT+  | otherwise                   = GT+subsetCmp t1@(Tip kx _) (Bin p m l r)+  | nomatch kx p m = GT+  | zero kx m      = case subsetCmp t1 l of GT -> GT ; _ -> LT+  | otherwise      = case subsetCmp t1 r of GT -> GT ; _ -> LT+subsetCmp (Tip _ _) Nil = GT -- disjoint+subsetCmp Nil Nil = EQ+subsetCmp Nil _   = LT++-- | \(O(n+m)\). Is this a subset?+-- @(s1 \`isSubsetOf\` s2)@ tells whether @s1@ is a subset of @s2@.++isSubsetOf :: Word64Set -> Word64Set -> Bool+isSubsetOf t1@(Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)+  | shorter m1 m2  = False+  | shorter m2 m1  = match p1 p2 m2 && (if zero p1 m2 then isSubsetOf t1 l2+                                                      else isSubsetOf t1 r2)+  | otherwise      = (p1==p2) && isSubsetOf l1 l2 && isSubsetOf r1 r2+isSubsetOf (Bin _ _ _ _) _  = False+isSubsetOf (Tip kx1 bm1) (Tip kx2 bm2) = kx1 == kx2 && bm1 .&. complement bm2 == 0+isSubsetOf t1@(Tip kx _) (Bin p m l r)+  | nomatch kx p m = False+  | zero kx m      = isSubsetOf t1 l+  | otherwise      = isSubsetOf t1 r+isSubsetOf (Tip _ _) Nil = False+isSubsetOf Nil _         = True+++{--------------------------------------------------------------------+  Disjoint+--------------------------------------------------------------------}+-- | \(O(n+m)\). Check whether two sets are disjoint (i.e. their intersection+--   is empty).+--+-- > disjoint (fromList [2,4,6])   (fromList [1,3])     == True+-- > disjoint (fromList [2,4,6,8]) (fromList [2,3,5,7]) == False+-- > disjoint (fromList [1,2])     (fromList [1,2,3,4]) == False+-- > disjoint (fromList [])        (fromList [])        == True+--+-- @since 0.5.11+disjoint :: Word64Set -> Word64Set -> Bool+disjoint t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)+  | shorter m1 m2  = disjoint1+  | shorter m2 m1  = disjoint2+  | p1 == p2       = disjoint l1 l2 && disjoint r1 r2+  | otherwise      = True+  where+    disjoint1 | nomatch p2 p1 m1  = True+              | zero p2 m1        = disjoint l1 t2+              | otherwise         = disjoint r1 t2++    disjoint2 | nomatch p1 p2 m2  = True+              | zero p1 m2        = disjoint t1 l2+              | otherwise         = disjoint t1 r2++disjoint t1@(Bin _ _ _ _) (Tip kx2 bm2) = disjointBM t1+  where disjointBM (Bin p1 m1 l1 r1) | nomatch kx2 p1 m1 = True+                                     | zero kx2 m1       = disjointBM l1+                                     | otherwise         = disjointBM r1+        disjointBM (Tip kx1 bm1) | kx1 == kx2 = (bm1 .&. bm2) == 0+                                 | otherwise = True+        disjointBM Nil = True++disjoint (Bin _ _ _ _) Nil = True++disjoint (Tip kx1 bm1) t2 = disjointBM t2+  where disjointBM (Bin p2 m2 l2 r2) | nomatch kx1 p2 m2 = True+                                     | zero kx1 m2       = disjointBM l2+                                     | otherwise         = disjointBM r2+        disjointBM (Tip kx2 bm2) | kx1 == kx2 = (bm1 .&. bm2) == 0+                                 | otherwise = True+        disjointBM Nil = True++disjoint Nil _ = True+++{--------------------------------------------------------------------+  Filter+--------------------------------------------------------------------}+-- | \(O(n)\). Filter all elements that satisfy some predicate.+filter :: (Key -> Bool) -> Word64Set -> Word64Set+filter predicate t+  = case t of+      Bin p m l r+        -> bin p m (filter predicate l) (filter predicate r)+      Tip kx bm+        -> tip kx (foldl'Bits 0 (bitPred kx) 0 bm)+      Nil -> Nil+  where bitPred kx bm bi | predicate (kx + bi) = bm .|. bitmapOfSuffix bi+                         | otherwise           = bm+        {-# INLINE bitPred #-}++-- | \(O(n)\). partition the set according to some predicate.+partition :: (Key -> Bool) -> Word64Set -> (Word64Set,Word64Set)+partition predicate0 t0 = toPair $ go predicate0 t0+  where+    go predicate t+      = case t of+          Bin p m l r+            -> let (l1 :*: l2) = go predicate l+                   (r1 :*: r2) = go predicate r+               in bin p m l1 r1 :*: bin p m l2 r2+          Tip kx bm+            -> let bm1 = foldl'Bits 0 (bitPred kx) 0 bm+               in  tip kx bm1 :*: tip kx (bm `xor` bm1)+          Nil -> (Nil :*: Nil)+      where bitPred kx bm bi | predicate (kx + bi) = bm .|. bitmapOfSuffix bi+                             | otherwise           = bm+            {-# INLINE bitPred #-}++-- | \(O(\min(n,W))\). Take while a predicate on the elements holds.+-- The user is responsible for ensuring that for all @Int@s, @j \< k ==\> p j \>= p k@.+-- See note at 'spanAntitone'.+--+-- @+-- takeWhileAntitone p = 'fromDistinctAscList' . 'Data.List.takeWhile' p . 'toList'+-- takeWhileAntitone p = 'filter' p+-- @+--+-- @since 0.6.7+takeWhileAntitone :: (Key -> Bool) -> Word64Set -> Word64Set+takeWhileAntitone predicate t =+  case t of+    Bin p m l r+      | m < 0 ->+        if predicate 0 -- handle negative numbers.+        then bin p m (go predicate l) r+        else go predicate r+    _ -> go predicate t+  where+    go predicate' (Bin p m l r)+      | predicate' $! p+m = bin p m l (go predicate' r)+      | otherwise         = go predicate' l+    go predicate' (Tip kx bm) = tip kx (takeWhileAntitoneBits kx predicate' bm)+    go _ Nil = Nil++-- | \(O(\min(n,W))\). Drop while a predicate on the elements holds.+-- The user is responsible for ensuring that for all @Int@s, @j \< k ==\> p j \>= p k@.+-- See note at 'spanAntitone'.+--+-- @+-- dropWhileAntitone p = 'fromDistinctAscList' . 'Data.List.dropWhile' p . 'toList'+-- dropWhileAntitone p = 'filter' (not . p)+-- @+--+-- @since 0.6.7+dropWhileAntitone :: (Key -> Bool) -> Word64Set -> Word64Set+dropWhileAntitone predicate t =+  case t of+    Bin p m l r+      | m < 0 ->+        if predicate 0 -- handle negative numbers.+        then go predicate l+        else bin p m l (go predicate r)+    _ -> go predicate t+  where+    go predicate' (Bin p m l r)+      | predicate' $! p+m = go predicate' r+      | otherwise         = bin p m (go predicate' l) r+    go predicate' (Tip kx bm) = tip kx (bm `xor` takeWhileAntitoneBits kx predicate' bm)+    go _ Nil = Nil++-- | \(O(\min(n,W))\). Divide a set at the point where a predicate on the elements stops holding.+-- The user is responsible for ensuring that for all @Int@s, @j \< k ==\> p j \>= p k@.+--+-- @+-- spanAntitone p xs = ('takeWhileAntitone' p xs, 'dropWhileAntitone' p xs)+-- spanAntitone p xs = 'partition' p xs+-- @+--+-- Note: if @p@ is not actually antitone, then @spanAntitone@ will split the set+-- at some /unspecified/ point.+--+-- @since 0.6.7+spanAntitone :: (Key -> Bool) -> Word64Set -> (Word64Set, Word64Set)+spanAntitone predicate t =+  case t of+    Bin p m l r+      | m < 0 ->+        if predicate 0 -- handle negative numbers.+        then+          case go predicate l of+            (lt :*: gt) ->+              let !lt' = bin p m lt r+              in (lt', gt)+        else+          case go predicate r of+            (lt :*: gt) ->+              let !gt' = bin p m l gt+              in (lt, gt')+    _ -> case go predicate t of+          (lt :*: gt) -> (lt, gt)+  where+    go predicate' (Bin p m l r)+      | predicate' $! p+m = case go predicate' r of (lt :*: gt) -> bin p m l lt :*: gt+      | otherwise         = case go predicate' l of (lt :*: gt) -> lt :*: bin p m gt r+    go predicate' (Tip kx bm) = let bm' = takeWhileAntitoneBits kx predicate' bm+                                in (tip kx bm' :*: tip kx (bm `xor` bm'))+    go _ Nil = (Nil :*: Nil)++-- | \(O(\min(n,W))\). The expression (@'split' x set@) is a pair @(set1,set2)@+-- where @set1@ comprises the elements of @set@ less than @x@ and @set2@+-- comprises the elements of @set@ greater than @x@.+--+-- > split 3 (fromList [1..5]) == (fromList [1,2], fromList [4,5])+split :: Key -> Word64Set -> (Word64Set,Word64Set)+split x t =+  case t of+    Bin p m l r+      | m < 0 ->+        if x >= 0  -- handle negative numbers.+        then+          case go x l of+            (lt :*: gt) ->+              let !lt' = bin p m lt r+              in (lt', gt)+        else+          case go x r of+            (lt :*: gt) ->+              let !gt' = bin p m l gt+              in (lt, gt')+    _ -> case go x t of+          (lt :*: gt) -> (lt, gt)+  where+    go !x' t'@(Bin p m l r)+        | nomatch x' p m = if x' < p then (Nil :*: t') else (t' :*: Nil)+        | zero x' m      = case go x' l of (lt :*: gt) -> lt :*: bin p m gt r+        | otherwise      = case go x' r of (lt :*: gt) -> bin p m l lt :*: gt+    go x' t'@(Tip kx' bm)+        | kx' > x'          = (Nil :*: t')+          -- equivalent to kx' > prefixOf x'+        | kx' < prefixOf x' = (t' :*: Nil)+        | otherwise = tip kx' (bm .&. lowerBitmap) :*: tip kx' (bm .&. higherBitmap)+            where lowerBitmap = bitmapOf x' - 1+                  higherBitmap = complement (lowerBitmap + bitmapOf x')+    go _ Nil = (Nil :*: Nil)++-- | \(O(\min(n,W))\). Performs a 'split' but also returns whether the pivot+-- element was found in the original set.+splitMember :: Key -> Word64Set -> (Word64Set,Bool,Word64Set)+splitMember x t =+  case t of+    Bin p m l r+      | m < 0 ->+        if x >= 0 -- handle negative numbers.+        then+          case go x l of+            (lt, fnd, gt) ->+              let !lt' = bin p m lt r+              in (lt', fnd, gt)+        else+          case go x r of+            (lt, fnd, gt) ->+              let !gt' = bin p m l gt+              in (lt, fnd, gt')+    _ -> go x t+  where+    go x' t'@(Bin p m l r)+        | nomatch x' p m = if x' < p then (Nil, False, t') else (t', False, Nil)+        | zero x' m =+          case go x' l of+            (lt, fnd, gt) ->+              let !gt' = bin p m gt r+              in (lt, fnd, gt')+        | otherwise =+          case go x' r of+            (lt, fnd, gt) ->+              let !lt' = bin p m l lt+              in (lt', fnd, gt)+    go x' t'@(Tip kx' bm)+        | kx' > x'          = (Nil, False, t')+          -- equivalent to kx' > prefixOf x'+        | kx' < prefixOf x' = (t', False, Nil)+        | otherwise = let !lt = tip kx' (bm .&. lowerBitmap)+                          !found = (bm .&. bitmapOfx') /= 0+                          !gt = tip kx' (bm .&. higherBitmap)+                      in (lt, found, gt)+            where bitmapOfx' = bitmapOf x'+                  lowerBitmap = bitmapOfx' - 1+                  higherBitmap = complement (lowerBitmap + bitmapOfx')+    go _ Nil = (Nil, False, Nil)++{----------------------------------------------------------------------+  Min/Max+----------------------------------------------------------------------}++-- | \(O(\min(n,W))\). Retrieves the maximal key of the set, and the set+-- stripped of that element, or 'Nothing' if passed an empty set.+maxView :: Word64Set -> Maybe (Key, Word64Set)+maxView t =+  case t of Nil -> Nothing+            Bin p m l r | m < 0 -> case go l of (result, l') -> Just (result, bin p m l' r)+            _ -> Just (go t)+  where+    go (Bin p m l r) = case go r of (result, r') -> (result, bin p m l r')+    go (Tip kx bm) = case highestBitSet bm of bi -> (kx + bi, tip kx (bm .&. complement (bitmapOfSuffix bi)))+    go Nil = error "maxView Nil"++-- | \(O(\min(n,W))\). Retrieves the minimal key of the set, and the set+-- stripped of that element, or 'Nothing' if passed an empty set.+minView :: Word64Set -> Maybe (Key, Word64Set)+minView t =+  case t of Nil -> Nothing+            Bin p m l r | m < 0 -> case go r of (result, r') -> Just (result, bin p m l r')+            _ -> Just (go t)+  where+    go (Bin p m l r) = case go l of (result, l') -> (result, bin p m l' r)+    go (Tip kx bm) = case lowestBitSet bm of bi -> (kx + bi, tip kx (bm .&. complement (bitmapOfSuffix bi)))+    go Nil = error "minView Nil"++-- | \(O(\min(n,W))\). Delete and find the minimal element.+--+-- > deleteFindMin set = (findMin set, deleteMin set)+deleteFindMin :: Word64Set -> (Key, Word64Set)+deleteFindMin = fromMaybe (error "deleteFindMin: empty set has no minimal element") . minView++-- | \(O(\min(n,W))\). Delete and find the maximal element.+--+-- > deleteFindMax set = (findMax set, deleteMax set)+deleteFindMax :: Word64Set -> (Key, Word64Set)+deleteFindMax = fromMaybe (error "deleteFindMax: empty set has no maximal element") . maxView+++-- | \(O(\min(n,W))\). The minimal element of the set.+findMin :: Word64Set -> Key+findMin Nil = error "findMin: empty set has no minimal element"+findMin (Tip kx bm) = kx + lowestBitSet bm+findMin (Bin _ m l r)+  |   m < 0   = find r+  | otherwise = find l+    where find (Tip kx bm) = kx + lowestBitSet bm+          find (Bin _ _ l' _) = find l'+          find Nil            = error "findMin Nil"++-- | \(O(\min(n,W))\). The maximal element of a set.+findMax :: Word64Set -> Key+findMax Nil = error "findMax: empty set has no maximal element"+findMax (Tip kx bm) = kx + highestBitSet bm+findMax (Bin _ m l r)+  |   m < 0   = find l+  | otherwise = find r+    where find (Tip kx bm) = kx + highestBitSet bm+          find (Bin _ _ _ r') = find r'+          find Nil            = error "findMax Nil"+++-- | \(O(\min(n,W))\). Delete the minimal element. Returns an empty set if the set is empty.+--+-- Note that this is a change of behaviour for consistency with 'Data.Set.Set' &#8211;+-- versions prior to 0.5 threw an error if the 'Word64Set' was already empty.+deleteMin :: Word64Set -> Word64Set+deleteMin = maybe Nil snd . minView++-- | \(O(\min(n,W))\). Delete the maximal element. Returns an empty set if the set is empty.+--+-- Note that this is a change of behaviour for consistency with 'Data.Set.Set' &#8211;+-- versions prior to 0.5 threw an error if the 'Word64Set' was already empty.+deleteMax :: Word64Set -> Word64Set+deleteMax = maybe Nil snd . maxView++{----------------------------------------------------------------------+  Map+----------------------------------------------------------------------}++-- | \(O(n \min(n,W))\).+-- @'map' f s@ is the set obtained by applying @f@ to each element of @s@.+--+-- It's worth noting that the size of the result may be smaller if,+-- for some @(x,y)@, @x \/= y && f x == f y@++map :: (Key -> Key) -> Word64Set -> Word64Set+map f = fromList . List.map f . toList++-- | \(O(n)\). The+--+-- @'mapMonotonic' f s == 'map' f s@, but works only when @f@ is strictly increasing.+-- /The precondition is not checked./+-- Semi-formally, we have:+--+-- > and [x < y ==> f x < f y | x <- ls, y <- ls]+-- >                     ==> mapMonotonic f s == map f s+-- >     where ls = toList s+--+-- @since 0.6.3.1++-- Note that for now the test is insufficient to support any fancier implementation.+mapMonotonic :: (Key -> Key) -> Word64Set -> Word64Set+mapMonotonic f = fromDistinctAscList . List.map f . toAscList+++{--------------------------------------------------------------------+  Fold+--------------------------------------------------------------------}+-- | \(O(n)\). Fold the elements in the set using the given right-associative+-- binary operator. This function is an equivalent of 'foldr' and is present+-- for compatibility only.+--+-- /Please note that fold will be deprecated in the future and removed./+fold :: (Key -> b -> b) -> b -> Word64Set -> b+fold = foldr+{-# INLINE fold #-}++-- | \(O(n)\). Fold the elements in the set using the given right-associative+-- binary operator, such that @'foldr' f z == 'Prelude.foldr' f z . 'toAscList'@.+--+-- For example,+--+-- > toAscList set = foldr (:) [] set+foldr :: (Key -> b -> b) -> b -> Word64Set -> b+foldr f z = \t ->      -- Use lambda t to be inlinable with two arguments only.+  case t of Bin _ m l r | m < 0 -> go (go z l) r -- put negative numbers before+                        | otherwise -> go (go z r) l+            _ -> go z t+  where+    go z' Nil           = z'+    go z' (Tip kx bm)   = foldrBits kx f z' bm+    go z' (Bin _ _ l r) = go (go z' r) l+{-# INLINE foldr #-}++-- | \(O(n)\). A strict version of 'foldr'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldr' :: (Key -> b -> b) -> b -> Word64Set -> b+foldr' f z = \t ->      -- Use lambda t to be inlinable with two arguments only.+  case t of Bin _ m l r | m < 0 -> go (go z l) r -- put negative numbers before+                        | otherwise -> go (go z r) l+            _ -> go z t+  where+    go !z' Nil           = z'+    go z' (Tip kx bm)   = foldr'Bits kx f z' bm+    go z' (Bin _ _ l r) = go (go z' r) l+{-# INLINE foldr' #-}++-- | \(O(n)\). Fold the elements in the set using the given left-associative+-- binary operator, such that @'foldl' f z == 'Prelude.foldl' f z . 'toAscList'@.+--+-- For example,+--+-- > toDescList set = foldl (flip (:)) [] set+foldl :: (a -> Key -> a) -> a -> Word64Set -> a+foldl f z = \t ->      -- Use lambda t to be inlinable with two arguments only.+  case t of Bin _ m l r | m < 0 -> go (go z r) l -- put negative numbers before+                        | otherwise -> go (go z l) r+            _ -> go z t+  where+    go z' Nil           = z'+    go z' (Tip kx bm)   = foldlBits kx f z' bm+    go z' (Bin _ _ l r) = go (go z' l) r+{-# INLINE foldl #-}++-- | \(O(n)\). A strict version of 'foldl'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldl' :: (a -> Key -> a) -> a -> Word64Set -> a+foldl' f z = \t ->      -- Use lambda t to be inlinable with two arguments only.+  case t of Bin _ m l r | m < 0 -> go (go z r) l -- put negative numbers before+                        | otherwise -> go (go z l) r+            _ -> go z t+  where+    go !z' Nil           = z'+    go z' (Tip kx bm)   = foldl'Bits kx f z' bm+    go z' (Bin _ _ l r) = go (go z' l) r+{-# INLINE foldl' #-}++{--------------------------------------------------------------------+  List variations+--------------------------------------------------------------------}+-- | \(O(n)\). An alias of 'toAscList'. The elements of a set in ascending order.+-- Subject to list fusion.+elems :: Word64Set -> [Key]+elems+  = toAscList++{--------------------------------------------------------------------+  Lists+--------------------------------------------------------------------}++#ifdef __GLASGOW_HASKELL__+-- | @since 0.5.6.2+instance GHC.Exts.IsList Word64Set where+  type Item Word64Set = Key+  fromList = fromList+  toList   = toList+#endif++-- | \(O(n)\). Convert the set to a list of elements. Subject to list fusion.+toList :: Word64Set -> [Key]+toList+  = toAscList++-- | \(O(n)\). Convert the set to an ascending list of elements. Subject to list+-- fusion.+toAscList :: Word64Set -> [Key]+toAscList = foldr (:) []++-- | \(O(n)\). Convert the set to a descending list of elements. Subject to list+-- fusion.+toDescList :: Word64Set -> [Key]+toDescList = foldl (flip (:)) []++-- List fusion for the list generating functions.+#if __GLASGOW_HASKELL__+-- The foldrFB and foldlFB are foldr and foldl equivalents, used for list fusion.+-- They are important to convert unfused to{Asc,Desc}List back, see mapFB in prelude.+foldrFB :: (Key -> b -> b) -> b -> Word64Set -> b+foldrFB = foldr+{-# INLINE[0] foldrFB #-}+foldlFB :: (a -> Key -> a) -> a -> Word64Set -> a+foldlFB = foldl+{-# INLINE[0] foldlFB #-}++-- Inline elems and toList, so that we need to fuse only toAscList.+{-# INLINE elems #-}+{-# INLINE toList #-}++-- The fusion is enabled up to phase 2 included. If it does not succeed,+-- convert in phase 1 the expanded to{Asc,Desc}List calls back to+-- to{Asc,Desc}List.  In phase 0, we inline fold{lr}FB (which were used in+-- a list fusion, otherwise it would go away in phase 1), and let compiler do+-- whatever it wants with to{Asc,Desc}List -- it was forbidden to inline it+-- before phase 0, otherwise the fusion rules would not fire at all.+{-# NOINLINE[0] toAscList #-}+{-# NOINLINE[0] toDescList #-}+{-# RULES "Word64Set.toAscList" [~1] forall s . toAscList s = GHC.Exts.build (\c n -> foldrFB c n s) #-}+{-# RULES "Word64Set.toAscListBack" [1] foldrFB (:) [] = toAscList #-}+{-# RULES "Word64Set.toDescList" [~1] forall s . toDescList s = GHC.Exts.build (\c n -> foldlFB (\xs x -> c x xs) n s) #-}+{-# RULES "Word64Set.toDescListBack" [1] foldlFB (\xs x -> x : xs) [] = toDescList #-}+#endif+++-- | \(O(n \min(n,W))\). Create a set from a list of integers.+fromList :: [Key] -> Word64Set+fromList xs+  = Foldable.foldl' ins empty xs+  where+    ins t x  = insert x t++-- | \(O(n)\). Build a set from an ascending list of elements.+-- /The precondition (input list is ascending) is not checked./+fromAscList :: [Key] -> Word64Set+fromAscList = fromMonoList+{-# NOINLINE fromAscList #-}++-- | \(O(n)\). Build a set from an ascending list of distinct elements.+-- /The precondition (input list is strictly ascending) is not checked./+fromDistinctAscList :: [Key] -> Word64Set+fromDistinctAscList = fromAscList+{-# INLINE fromDistinctAscList #-}++-- | \(O(n)\). Build a set from a monotonic list of elements.+--+-- The precise conditions under which this function works are subtle:+-- For any branch mask, keys with the same prefix w.r.t. the branch+-- mask must occur consecutively in the list.+fromMonoList :: [Key] -> Word64Set+fromMonoList []         = Nil+fromMonoList (kx : zs1) = addAll' (prefixOf kx) (bitmapOf kx) zs1+  where+    -- `addAll'` collects all keys with the prefix `px` into a single+    -- bitmap, and then proceeds with `addAll`.+    addAll' !px !bm []+        = Tip px bm+    addAll' !px !bm (ky : zs)+        | px == prefixOf ky+        = addAll' px (bm .|. bitmapOf ky) zs+        -- inlined: | otherwise = addAll px (Tip px bm) (ky : zs)+        | py <- prefixOf ky+        , m <- branchMask px py+        , Inserted ty zs' <- addMany' m py (bitmapOf ky) zs+        = addAll px (linkWithMask m py ty {-px-} (Tip px bm)) zs'++    -- for `addAll` and `addMany`, px is /a/ prefix inside the tree `tx`+    -- `addAll` consumes the rest of the list, adding to the tree `tx`+    addAll !_px !tx []+        = tx+    addAll !px !tx (ky : zs)+        | py <- prefixOf ky+        , m <- branchMask px py+        , Inserted ty zs' <- addMany' m py (bitmapOf ky) zs+        = addAll px (linkWithMask m py ty {-px-} tx) zs'++    -- `addMany'` is similar to `addAll'`, but proceeds with `addMany'`.+    addMany' !_m !px !bm []+        = Inserted (Tip px bm) []+    addMany' !m !px !bm zs0@(ky : zs)+        | px == prefixOf ky+        = addMany' m px (bm .|. bitmapOf ky) zs+        -- inlined: | otherwise = addMany m px (Tip px bm) (ky : zs)+        | mask px m /= mask ky m+        = Inserted (Tip (prefixOf px) bm) zs0+        | py <- prefixOf ky+        , mxy <- branchMask px py+        , Inserted ty zs' <- addMany' mxy py (bitmapOf ky) zs+        = addMany m px (linkWithMask mxy py ty {-px-} (Tip px bm)) zs'++    -- `addAll` adds to `tx` all keys whose prefix w.r.t. `m` agrees with `px`.+    addMany !_m !_px tx []+        = Inserted tx []+    addMany !m !px tx zs0@(ky : zs)+        | mask px m /= mask ky m+        = Inserted tx zs0+        | py <- prefixOf ky+        , mxy <- branchMask px py+        , Inserted ty zs' <- addMany' mxy py (bitmapOf ky) zs+        = addMany m px (linkWithMask mxy py ty {-px-} tx) zs'+{-# INLINE fromMonoList #-}++data Inserted = Inserted !Word64Set ![Key]++{--------------------------------------------------------------------+  Eq+--------------------------------------------------------------------}+instance Eq Word64Set where+  t1 == t2  = equal t1 t2+  t1 /= t2  = nequal t1 t2++equal :: Word64Set -> Word64Set -> Bool+equal (Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)+  = (m1 == m2) && (p1 == p2) && (equal l1 l2) && (equal r1 r2)+equal (Tip kx1 bm1) (Tip kx2 bm2)+  = kx1 == kx2 && bm1 == bm2+equal Nil Nil = True+equal _   _   = False++nequal :: Word64Set -> Word64Set -> Bool+nequal (Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)+  = (m1 /= m2) || (p1 /= p2) || (nequal l1 l2) || (nequal r1 r2)+nequal (Tip kx1 bm1) (Tip kx2 bm2)+  = kx1 /= kx2 || bm1 /= bm2+nequal Nil Nil = False+nequal _   _   = True++{--------------------------------------------------------------------+  Ord+--------------------------------------------------------------------}++instance Ord Word64Set where+    compare s1 s2 = compare (toAscList s1) (toAscList s2)+    -- tentative implementation. See if more efficient exists.++{--------------------------------------------------------------------+  Show+--------------------------------------------------------------------}+instance Show Word64Set where+  showsPrec p xs = showParen (p > 10) $+    showString "fromList " . shows (toList xs)++{--------------------------------------------------------------------+  Read+--------------------------------------------------------------------}+instance Read Word64Set where+#ifdef __GLASGOW_HASKELL__+  readPrec = parens $ prec 10 $ do+    Ident "fromList" <- lexP+    xs <- readPrec+    return (fromList xs)++  readListPrec = readListPrecDefault+#else+  readsPrec p = readParen (p > 10) $ \ r -> do+    ("fromList",s) <- lex r+    (xs,t) <- reads s+    return (fromList xs,t)+#endif++{--------------------------------------------------------------------+  NFData+--------------------------------------------------------------------}++-- The Word64Set constructors consist only of strict fields of Ints and+-- Word64Sets, thus the default NFData instance which evaluates to whnf+-- should suffice+instance NFData Word64Set where rnf x = seq x ()++{--------------------------------------------------------------------+  Debugging+--------------------------------------------------------------------}+-- | \(O(n \min(n,W))\). Show the tree that implements the set. The tree is shown+-- in a compressed, hanging format.+showTree :: Word64Set -> String+showTree s+  = showTreeWith True False s+++{- | \(O(n \min(n,W))\). The expression (@'showTreeWith' hang wide map@) shows+ the tree that implements the set. If @hang@ is+ 'True', a /hanging/ tree is shown otherwise a rotated tree is shown. If+ @wide@ is 'True', an extra wide version is shown.+-}+showTreeWith :: Bool -> Bool -> Word64Set -> String+showTreeWith hang wide t+  | hang      = (showsTreeHang wide [] t) ""+  | otherwise = (showsTree wide [] [] t) ""++showsTree :: Bool -> [String] -> [String] -> Word64Set -> ShowS+showsTree wide lbars rbars t+  = case t of+      Bin p m l r+          -> showsTree wide (withBar rbars) (withEmpty rbars) r .+             showWide wide rbars .+             showsBars lbars . showString (showBin p m) . showString "\n" .+             showWide wide lbars .+             showsTree wide (withEmpty lbars) (withBar lbars) l+      Tip kx bm+          -> showsBars lbars . showString " " . shows kx . showString " + " .+                                                showsBitMap bm . showString "\n"+      Nil -> showsBars lbars . showString "|\n"++showsTreeHang :: Bool -> [String] -> Word64Set -> ShowS+showsTreeHang wide bars t+  = case t of+      Bin p m l r+          -> showsBars bars . showString (showBin p m) . showString "\n" .+             showWide wide bars .+             showsTreeHang wide (withBar bars) l .+             showWide wide bars .+             showsTreeHang wide (withEmpty bars) r+      Tip kx bm+          -> showsBars bars . showString " " . shows kx . showString " + " .+                                               showsBitMap bm . showString "\n"+      Nil -> showsBars bars . showString "|\n"++showBin :: Prefix -> Mask -> String+showBin _ _+  = "*" -- ++ show (p,m)++showWide :: Bool -> [String] -> String -> String+showWide wide bars+  | wide      = showString (concat (reverse bars)) . showString "|\n"+  | otherwise = id++showsBars :: [String] -> ShowS+showsBars [] = id+showsBars (_ : tl) = showString (concat (reverse tl)) . showString node++showsBitMap :: Word64 -> ShowS+showsBitMap = showString . showBitMap++showBitMap :: Word64 -> String+showBitMap w = show $ foldrBits 0 (:) [] w++node :: String+node           = "+--"++withBar, withEmpty :: [String] -> [String]+withBar bars   = "|  ":bars+withEmpty bars = "   ":bars+++{--------------------------------------------------------------------+  Helpers+--------------------------------------------------------------------}+{--------------------------------------------------------------------+  Link+--------------------------------------------------------------------}+link :: Prefix -> Word64Set -> Prefix -> Word64Set -> Word64Set+link p1 t1 p2 t2 = linkWithMask (branchMask p1 p2) p1 t1 {-p2-} t2+{-# INLINE link #-}++-- `linkWithMask` is useful when the `branchMask` has already been computed+linkWithMask :: Mask -> Prefix -> Word64Set -> Word64Set -> Word64Set+linkWithMask m p1 t1 {-p2-} t2+  | zero p1 m = Bin p m t1 t2+  | otherwise = Bin p m t2 t1+  where+    p = mask p1 m+{-# INLINE linkWithMask #-}++{--------------------------------------------------------------------+  @bin@ assures that we never have empty trees within a tree.+--------------------------------------------------------------------}+bin :: Prefix -> Mask -> Word64Set -> Word64Set -> Word64Set+bin _ _ l Nil = l+bin _ _ Nil r = r+bin p m l r   = Bin p m l r+{-# INLINE bin #-}++{--------------------------------------------------------------------+  @tip@ assures that we never have empty bitmaps within a tree.+--------------------------------------------------------------------}+tip :: Prefix -> BitMap -> Word64Set+tip _ 0 = Nil+tip kx bm = Tip kx bm+{-# INLINE tip #-}+++{----------------------------------------------------------------------+  Functions that generate Prefix and BitMap of a Key or a Suffix.+----------------------------------------------------------------------}++suffixBitMask :: Word64+suffixBitMask = fromIntegral (finiteBitSize (undefined::Word64)) - 1+{-# INLINE suffixBitMask #-}++prefixBitMask :: Word64+prefixBitMask = complement suffixBitMask+{-# INLINE prefixBitMask #-}++prefixOf :: Word64 -> Prefix+prefixOf x = x .&. prefixBitMask+{-# INLINE prefixOf #-}++suffixOf :: Word64 -> Word64+suffixOf x = x .&. suffixBitMask+{-# INLINE suffixOf #-}++bitmapOfSuffix :: Word64 -> BitMap+bitmapOfSuffix s = 1 `shiftLL` fromIntegral s+{-# INLINE bitmapOfSuffix #-}++bitmapOf :: Word64 -> BitMap+bitmapOf x = bitmapOfSuffix (suffixOf x)+{-# INLINE bitmapOf #-}+++{--------------------------------------------------------------------+  Endian independent bit twiddling+--------------------------------------------------------------------}+-- Returns True iff the bits set in i and the Mask m are disjoint.+zero :: Word64 -> Mask -> Bool+zero i m+  = (natFromInt i) .&. (natFromInt m) == 0+{-# INLINE zero #-}++nomatch,match :: Word64 -> Prefix -> Mask -> Bool+nomatch i p m+  = (mask i m) /= p+{-# INLINE nomatch #-}++match i p m+  = (mask i m) == p+{-# INLINE match #-}++-- Suppose a is largest such that 2^a divides 2*m.+-- Then mask i m is i with the low a bits zeroed out.+mask :: Word64 -> Mask -> Prefix+mask i m+  = maskW (natFromInt i) (natFromInt m)+{-# INLINE mask #-}++{--------------------------------------------------------------------+  Big endian operations+--------------------------------------------------------------------}+maskW :: Nat -> Nat -> Prefix+maskW i m+  = intFromNat (i .&. (complement (m-1) `xor` m))+{-# INLINE maskW #-}++shorter :: Mask -> Mask -> Bool+shorter m1 m2+  = (natFromInt m1) > (natFromInt m2)+{-# INLINE shorter #-}++branchMask :: Prefix -> Prefix -> Mask+branchMask p1 p2+  = intFromNat (highestBitMask (natFromInt p1 `xor` natFromInt p2))+{-# INLINE branchMask #-}++{----------------------------------------------------------------------+  To get best performance, we provide fast implementations of+  lowestBitSet, highestBitSet and fold[lr][l]Bits for GHC.+  If the intel bsf and bsr instructions ever become GHC primops,+  this code should be reimplemented using these.++  Performance of this code is crucial for folds, toList, filter, partition.++  The signatures of methods in question are placed after this comment.+----------------------------------------------------------------------}++lowestBitSet :: Nat -> Word64+highestBitSet :: Nat -> Word64+foldlBits :: Word64 -> (a -> Word64 -> a) -> a -> Nat -> a+foldl'Bits :: Word64 -> (a -> Word64 -> a) -> a -> Nat -> a+foldrBits :: Word64 -> (Word64 -> a -> a) -> a -> Nat -> a+foldr'Bits :: Word64 -> (Word64 -> a -> a) -> a -> Nat -> a+takeWhileAntitoneBits :: Word64 -> (Word64 -> Bool) -> Nat -> Nat++{-# INLINE lowestBitSet #-}+{-# INLINE highestBitSet #-}+{-# INLINE foldlBits #-}+{-# INLINE foldl'Bits #-}+{-# INLINE foldrBits #-}+{-# INLINE foldr'Bits #-}+{-# INLINE takeWhileAntitoneBits #-}++#if defined(__GLASGOW_HASKELL__)+indexOfTheOnlyBit :: Nat -> Word64+{-# INLINE indexOfTheOnlyBit #-}+indexOfTheOnlyBit bitmask = fromIntegral $ countTrailingZeros bitmask++lowestBitSet x = fromIntegral $ countTrailingZeros x++highestBitSet x = fromIntegral $ 63 - countLeadingZeros x++lowestBitMask :: Nat -> Nat+lowestBitMask x = x .&. negate x+{-# INLINE lowestBitMask #-}++-- Reverse the order of bits in the Nat.+revNat :: Nat -> Nat+revNat x1 = case ((x1 `shiftRL` 1) .&. 0x5555555555555555) .|. ((x1 .&. 0x5555555555555555) `shiftLL` 1) of+              x2 -> case ((x2 `shiftRL` 2) .&. 0x3333333333333333) .|. ((x2 .&. 0x3333333333333333) `shiftLL` 2) of+                 x3 -> case ((x3 `shiftRL` 4) .&. 0x0F0F0F0F0F0F0F0F) .|. ((x3 .&. 0x0F0F0F0F0F0F0F0F) `shiftLL` 4) of+                   x4 -> case ((x4 `shiftRL` 8) .&. 0x00FF00FF00FF00FF) .|. ((x4 .&. 0x00FF00FF00FF00FF) `shiftLL` 8) of+                     x5 -> case ((x5 `shiftRL` 16) .&. 0x0000FFFF0000FFFF) .|. ((x5 .&. 0x0000FFFF0000FFFF) `shiftLL` 16) of+                       x6 -> ( x6 `shiftRL` 32             ) .|. ( x6               `shiftLL` 32);++foldlBits prefix f z bitmap = go bitmap z+  where go 0 acc = acc+        go bm acc = go (bm `xor` bitmask) ((f acc) $! (prefix+bi))+          where+            !bitmask = lowestBitMask bm+            !bi = indexOfTheOnlyBit bitmask++foldl'Bits prefix f z bitmap = go bitmap z+  where go 0 acc = acc+        go bm !acc = go (bm `xor` bitmask) ((f acc) $! (prefix+bi))+          where !bitmask = lowestBitMask bm+                !bi = indexOfTheOnlyBit bitmask++foldrBits prefix f z bitmap = go (revNat bitmap) z+  where go 0 acc = acc+        go bm acc = go (bm `xor` bitmask) ((f $! (prefix+63-bi)) acc)+          where !bitmask = lowestBitMask bm+                !bi = indexOfTheOnlyBit bitmask+++foldr'Bits prefix f z bitmap = go (revNat bitmap) z+  where go 0 acc = acc+        go bm !acc = go (bm `xor` bitmask) ((f $! (prefix+63-bi)) acc)+          where !bitmask = lowestBitMask bm+                !bi = indexOfTheOnlyBit bitmask++takeWhileAntitoneBits prefix predicate bitmap =+  -- Binary search for the first index where the predicate returns false, but skip a predicate+  -- call if the high half of the current range is empty. This ensures+  -- min (log2 64 + 1 = 7) (popcount bitmap) predicate calls.+  let next d h (n',b') =+        if n' .&. h /= 0 && (predicate $! prefix + fromIntegral (b'+d)) then (n' `shiftRL` d, b'+d) else (n',b')+      {-# INLINE next #-}+      (_,b) = next 1  0x2 $+              next 2  0xC $+              next 4  0xF0 $+              next 8  0xFF00 $+              next 16 0xFFFF0000 $+              next 32 0xFFFFFFFF00000000 $+              (bitmap,0)+      m = if b /= 0 || (bitmap .&. 0x1 /= 0 && predicate prefix)+          then ((2 `shiftLL` b) - 1)+          else ((1 `shiftLL` b) - 1)+  in bitmap .&. m++#else+{----------------------------------------------------------------------+  In general case we use logarithmic implementation of+  lowestBitSet and highestBitSet, which works up to bit sizes of 64.++  Folds are linear scans.+----------------------------------------------------------------------}++lowestBitSet n0 =+    let (n1,b1) = if n0 .&. 0xFFFFFFFF /= 0 then (n0,0)  else (n0 `shiftRL` 32, 32)+        (n2,b2) = if n1 .&. 0xFFFF /= 0     then (n1,b1) else (n1 `shiftRL` 16, 16+b1)+        (n3,b3) = if n2 .&. 0xFF /= 0       then (n2,b2) else (n2 `shiftRL` 8,  8+b2)+        (n4,b4) = if n3 .&. 0xF /= 0        then (n3,b3) else (n3 `shiftRL` 4,  4+b3)+        (n5,b5) = if n4 .&. 0x3 /= 0        then (n4,b4) else (n4 `shiftRL` 2,  2+b4)+        b6      = if n5 .&. 0x1 /= 0        then     b5  else                   1+b5+    in b6++highestBitSet n0 =+    let (n1,b1) = if n0 .&. 0xFFFFFFFF00000000 /= 0 then (n0 `shiftRL` 32, 32)    else (n0,0)+        (n2,b2) = if n1 .&. 0xFFFF0000 /= 0         then (n1 `shiftRL` 16, 16+b1) else (n1,b1)+        (n3,b3) = if n2 .&. 0xFF00 /= 0             then (n2 `shiftRL` 8,  8+b2)  else (n2,b2)+        (n4,b4) = if n3 .&. 0xF0 /= 0               then (n3 `shiftRL` 4,  4+b3)  else (n3,b3)+        (n5,b5) = if n4 .&. 0xC /= 0                then (n4 `shiftRL` 2,  2+b4)  else (n4,b4)+        b6      = if n5 .&. 0x2 /= 0                then                   1+b5   else     b5+    in b6++foldlBits prefix f z bm = let lb = lowestBitSet bm+                          in  go (prefix+lb) z (bm `shiftRL` lb)+  where go !_ acc 0 = acc+        go bi acc n | n `testBit` 0 = go (bi + 1) (f acc bi) (n `shiftRL` 1)+                    | otherwise     = go (bi + 1)    acc     (n `shiftRL` 1)++foldl'Bits prefix f z bm = let lb = lowestBitSet bm+                           in  go (prefix+lb) z (bm `shiftRL` lb)+  where go !_ !acc 0 = acc+        go bi acc n | n `testBit` 0 = go (bi + 1) (f acc bi) (n `shiftRL` 1)+                    | otherwise     = go (bi + 1)    acc     (n `shiftRL` 1)++foldrBits prefix f z bm = let lb = lowestBitSet bm+                          in  go (prefix+lb) (bm `shiftRL` lb)+  where go !_ 0 = z+        go bi n | n `testBit` 0 = f bi (go (bi + 1) (n `shiftRL` 1))+                | otherwise     =       go (bi + 1) (n `shiftRL` 1)++foldr'Bits prefix f z bm = let lb = lowestBitSet bm+                           in  go (prefix+lb) (bm `shiftRL` lb)+  where+        go !_ 0 = z+        go bi n | n `testBit` 0 = f bi $! go (bi + 1) (n `shiftRL` 1)+                | otherwise     =         go (bi + 1) (n `shiftRL` 1)++takeWhileAntitoneBits prefix predicate = foldl'Bits prefix f 0 -- Does not use antitone property+  where+    f acc bi | predicate bi = acc .|. bitmapOf bi+             | otherwise    = acc++#endif+++{--------------------------------------------------------------------+  Utilities+--------------------------------------------------------------------}++-- | \(O(1)\).  Decompose a set into pieces based on the structure of the underlying+-- tree.  This function is useful for consuming a set in parallel.+--+-- No guarantee is made as to the sizes of the pieces; an internal, but+-- deterministic process determines this.  However, it is guaranteed that the+-- pieces returned will be in ascending order (all elements in the first submap+-- less than all elements in the second, and so on).+--+-- Examples:+--+-- > splitRoot (fromList [1..120]) == [fromList [1..63],fromList [64..120]]+-- > splitRoot empty == []+--+--  Note that the current implementation does not return more than two subsets,+--  but you should not depend on this behaviour because it can change in the+--  future without notice. Also, the current version does not continue+--  splitting all the way to individual singleton sets -- it stops at some+--  point.+splitRoot :: Word64Set -> [Word64Set]+splitRoot Nil = []+-- NOTE: we don't currently split below Tip, but we could.+splitRoot x@(Tip _ _) = [x]+splitRoot (Bin _ m l r) | m < 0 = [r, l]+                        | otherwise = [l, r]+{-# INLINE splitRoot #-}
GHC/Driver/CmdLine.hs view
@@ -37,6 +37,7 @@  import Data.Function import Data.List (sortBy, intercalate, stripPrefix)+import Data.Word  import GHC.ResponseFile import Control.Exception (IOException, catch)@@ -75,7 +76,7 @@       go (OptPrefix k) = OptPrefix (\s -> go2 (k s))       go (OptIntSuffix k) = OptIntSuffix (\n -> go2 (k n))       go (IntSuffix k) = IntSuffix (\n -> go2 (k n))-      go (WordSuffix k) = WordSuffix (\s -> go2 (k s))+      go (Word64Suffix k) = Word64Suffix (\s -> go2 (k s))       go (FloatSuffix k) = FloatSuffix (\s -> go2 (k s))       go (PassFlag k) = PassFlag (\s -> go2 (k s))       go (AnySuffix k) = AnySuffix (\s -> go2 (k s))@@ -98,7 +99,7 @@     | OptPrefix (String -> EwM m ())       -- -f or -farg (i.e. the arg is optional)     | OptIntSuffix (Maybe Int -> EwM m ()) -- -f or -f=n; pass n to fn     | IntSuffix (Int -> EwM m ())          -- -f or -f=n; pass n to fn-    | WordSuffix (Word -> EwM m ())        -- -f or -f=n; pass n to fn+    | Word64Suffix (Word64 -> EwM m ())    -- -f or -f=n; pass n to fn     | FloatSuffix (Float -> EwM m ())      -- -f or -f=n; pass n to fn     | PassFlag  (String -> EwM m ())       -- -f; pass "-f" fn     | AnySuffix (String -> EwM m ())       -- -f or -farg; pass entire "-farg" to fn@@ -240,7 +241,7 @@         IntSuffix f | Just n <- parseInt rest_no_eq -> Right (f n, args)                     | otherwise -> Left ("malformed integer argument in " ++ dash_arg) -        WordSuffix f | Just n <- parseWord rest_no_eq -> Right (f n, args)+        Word64Suffix f | Just n <- parseWord64 rest_no_eq -> Right (f n, args)                      | otherwise -> Left ("malformed natural argument in " ++ dash_arg)          FloatSuffix f | Just n <- parseFloat rest_no_eq -> Right (f n, args)@@ -269,7 +270,7 @@                                             -- to improve error message (#12625) arg_ok (OptIntSuffix    _)  _    _   = True arg_ok (IntSuffix       _)  _    _   = True-arg_ok (WordSuffix      _)  _    _   = True+arg_ok (Word64Suffix    _)  _    _   = True arg_ok (FloatSuffix     _)  _    _   = True arg_ok (OptPrefix       _)  _    _   = True arg_ok (PassFlag        _)  rest _   = null rest@@ -285,8 +286,8 @@                  ((n,""):_) -> Just n                  _          -> Nothing -parseWord :: String -> Maybe Word-parseWord s = case reads s of+parseWord64 :: String -> Maybe Word64+parseWord64 s = case reads s of                  ((n,""):_) -> Just n                  _          -> Nothing 
GHC/Driver/DynFlags.hs view
@@ -117,6 +117,7 @@ import Control.Monad.Trans.Reader (ReaderT) import Control.Monad.Trans.Writer (WriterT) import Data.IORef+import Data.Word import System.IO import System.IO.Error (catchIOError) import System.Environment (lookupEnv)@@ -449,7 +450,7 @@   maxErrors             :: Maybe Int,    -- | Unique supply configuration for testing build determinism-  initialUnique         :: Word,+  initialUnique         :: Word64,   uniqueIncrement       :: Int,     -- 'Int' because it can be used to test uniques in decreasing order. 
GHC/Driver/Main.hs view
@@ -248,7 +248,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TyThing import GHC.Types.HpcInfo-import GHC.Types.Unique.Supply (uniqFromMask)+import GHC.Types.Unique.Supply (uniqFromTag) import GHC.Types.Unique.Set  import GHC.Utils.Fingerprint ( Fingerprint )@@ -2595,7 +2595,7 @@   --   -- The id has to be exported for the JS backend. This isn't required for the   -- byte-code interpreter but it does no harm to always do it.-  u <- uniqFromMask 'I'+  u <- uniqFromTag 'I'   let binding_name = mkSystemVarName u (fsLit ("BCO_toplevel"))   let binding_id   = mkExportedVanillaId binding_name (exprType simpl_expr) 
GHC/Driver/Make.hs view
@@ -155,7 +155,7 @@ import GHC.Types.Unique import GHC.Iface.Errors.Types -import qualified Data.IntSet as I+import qualified GHC.Data.Word64Set as W  -- ----------------------------------------------------------------------------- -- Loading the program@@ -340,10 +340,12 @@     -- Note also that we can't always infer the associated module name     -- directly from the filename argument.  See #13727.     is_known_module mod =-      (Map.lookup (moduleName (ms_mod mod)) mod_targets == Just (ms_unitid mod))+      is_module_target mod       ||       maybe False is_file_target (ml_hs_file (ms_location mod)) +    is_module_target mod = (moduleName (ms_mod mod), ms_unitid mod) `Set.member` mod_targets+     is_file_target file = Set.member (withoutExt file) file_targets      file_targets = Set.fromList (mapMaybe file_target targets)@@ -354,7 +356,7 @@         TargetFile file _ ->           Just (withoutExt (augmentByWorkingDirectory dflags file)) -    mod_targets = Map.fromList (mod_target <$> targets)+    mod_targets = Set.fromList (mod_target <$> targets)      mod_target Target {targetUnitId, targetId} =       case targetId of@@ -2834,12 +2836,12 @@ -}  -- See Note [ModuleNameSet, efficiency and space leaks]-type ModuleNameSet = M.Map UnitId I.IntSet+type ModuleNameSet = M.Map UnitId W.Word64Set  addToModuleNameSet :: UnitId -> ModuleName -> ModuleNameSet -> ModuleNameSet addToModuleNameSet uid mn s =   let k = (getKey $ getUnique $ mn)-  in M.insertWith (I.union) uid (I.singleton k) s+  in M.insertWith (W.union) uid (W.singleton k) s  -- | Wait for some dependencies to finish and then read from the given MVar. wait_deps_hug :: MVar HomeUnitGraph -> [BuildResult] -> ReaderT MakeEnv (MaybeT IO) (HomeUnitGraph, ModuleNameSet)@@ -2850,7 +2852,7 @@         let -- Restrict to things which are in the transitive closure to avoid retaining             -- reference to loop modules which have already been compiled by other threads.             -- See Note [ModuleNameSet, efficiency and space leaks]-            !new = udfmRestrictKeysSet (homeUnitEnv_hpt hme) (fromMaybe I.empty $ M.lookup  uid module_deps)+            !new = udfmRestrictKeysSet (homeUnitEnv_hpt hme) (fromMaybe W.empty $ M.lookup  uid module_deps)         in hme { homeUnitEnv_hpt = new }   return (unitEnv_mapWithKey pruneHomeUnitEnv hug, module_deps) @@ -2865,7 +2867,7 @@     Nothing -> return (hmis, new_deps)     Just hmi -> return (hmi:hmis, new_deps)   where-    unionModuleNameSet = M.unionWith I.union+    unionModuleNameSet = M.unionWith W.union   -- Executing the pipelines
GHC/Driver/Session.hs view
@@ -278,6 +278,7 @@ import qualified Data.List.NonEmpty as NE import qualified Data.Map as Map import qualified Data.Set as Set+import Data.Word import System.FilePath import Text.ParserCombinators.ReadP hiding (char) import Text.ParserCombinators.ReadP as R@@ -973,8 +974,8 @@                                OptIntSuffix $ \oi -> f oi >> deprecate message add_dep_message (IntSuffix f) message =                                   IntSuffix $ \i -> f i >> deprecate message-add_dep_message (WordSuffix f) message =-                                  WordSuffix $ \i -> f i >> deprecate message+add_dep_message (Word64Suffix f) message =+                                  Word64Suffix $ \i -> f i >> deprecate message add_dep_message (FloatSuffix f) message =                                 FloatSuffix $ \fl -> f fl >> deprecate message add_dep_message (PassFlag f) message =@@ -1765,7 +1766,7 @@   , make_ord_flag defGhcFlag "fmax-inline-memset-insns"       (intSuffix (\n d -> d { maxInlineMemsetInsns = n }))   , make_ord_flag defGhcFlag "dinitial-unique"-      (wordSuffix (\n d -> d { initialUnique = n }))+      (word64Suffix (\n d -> d { initialUnique = n }))   , make_ord_flag defGhcFlag "dunique-increment"       (intSuffix (\n d -> d { uniqueIncrement = n })) @@ -2994,8 +2995,8 @@ intSuffixM :: (Int -> DynFlags -> DynP DynFlags) -> OptKind (CmdLineP DynFlags) intSuffixM fn = IntSuffix (\n -> updM (fn n)) -wordSuffix :: (Word -> DynFlags -> DynFlags) -> OptKind (CmdLineP DynFlags)-wordSuffix fn = WordSuffix (\n -> upd (fn n))+word64Suffix :: (Word64 -> DynFlags -> DynFlags) -> OptKind (CmdLineP DynFlags)+word64Suffix fn = Word64Suffix (\n -> upd (fn n))  floatSuffix :: (Float -> DynFlags -> DynFlags) -> OptKind (CmdLineP DynFlags) floatSuffix fn = FloatSuffix (\n -> upd (fn n))
GHC/HsToCore/Breakpoints.hs view
@@ -27,16 +27,18 @@      breakArray <- GHCi.newBreakArray interp count     ccs <- mkCCSArray interp mod count entries+    mod_ptr <- GHCi.newModuleName interp (moduleName mod)     let            locsTicks  = listArray (0,count-1) [ tick_loc  t | t <- entries ]            varsTicks  = listArray (0,count-1) [ tick_ids  t | t <- entries ]            declsTicks = listArray (0,count-1) [ tick_path t | t <- entries ]     return $ emptyModBreaks-                       { modBreaks_flags = breakArray-                       , modBreaks_locs  = locsTicks-                       , modBreaks_vars  = varsTicks-                       , modBreaks_decls = declsTicks-                       , modBreaks_ccs   = ccs+                       { modBreaks_flags  = breakArray+                       , modBreaks_locs   = locsTicks+                       , modBreaks_vars   = varsTicks+                       , modBreaks_decls  = declsTicks+                       , modBreaks_ccs    = ccs+                       , modBreaks_module = mod_ptr                        }  mkCCSArray
GHC/HsToCore/Foreign/JavaScript.hs view
@@ -156,7 +156,7 @@    header_bits = maybe mempty idTag maybe_target   idTag i = let (tag, u) = unpkUnique (getUnique i)-            in  CHeader (char tag <> int u)+            in  CHeader (char tag <> word64 u)    fun_args     | null arg_info = empty -- text "void"
GHC/HsToCore/Match/Literal.hs view
@@ -64,6 +64,7 @@ import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Utils.Panic.Plain+import GHC.Utils.Unique (sameUnique)  import GHC.Data.FastString @@ -319,29 +320,29 @@  , Just (i, tc) <- lit  = if     -- These only show up via the 'HsOverLit' route-    | tc == intTyConName        -> check i tc minInt         maxInt-    | tc == wordTyConName       -> check i tc minWord        maxWord-    | tc == int8TyConName       -> check i tc (min' @Int8)   (max' @Int8)-    | tc == int16TyConName      -> check i tc (min' @Int16)  (max' @Int16)-    | tc == int32TyConName      -> check i tc (min' @Int32)  (max' @Int32)-    | tc == int64TyConName      -> check i tc (min' @Int64)  (max' @Int64)-    | tc == word8TyConName      -> check i tc (min' @Word8)  (max' @Word8)-    | tc == word16TyConName     -> check i tc (min' @Word16) (max' @Word16)-    | tc == word32TyConName     -> check i tc (min' @Word32) (max' @Word32)-    | tc == word64TyConName     -> check i tc (min' @Word64) (max' @Word64)-    | tc == naturalTyConName    -> checkPositive i tc+    | sameUnique tc intTyConName        -> check i tc minInt         maxInt+    | sameUnique tc wordTyConName       -> check i tc minWord        maxWord+    | sameUnique tc int8TyConName       -> check i tc (min' @Int8)   (max' @Int8)+    | sameUnique tc int16TyConName      -> check i tc (min' @Int16)  (max' @Int16)+    | sameUnique tc int32TyConName      -> check i tc (min' @Int32)  (max' @Int32)+    | sameUnique tc int64TyConName      -> check i tc (min' @Int64)  (max' @Int64)+    | sameUnique tc word8TyConName      -> check i tc (min' @Word8)  (max' @Word8)+    | sameUnique tc word16TyConName     -> check i tc (min' @Word16) (max' @Word16)+    | sameUnique tc word32TyConName     -> check i tc (min' @Word32) (max' @Word32)+    | sameUnique tc word64TyConName     -> check i tc (min' @Word64) (max' @Word64)+    | sameUnique tc naturalTyConName    -> checkPositive i tc      -- These only show up via the 'HsLit' route-    | tc == intPrimTyConName    -> check i tc minInt         maxInt-    | tc == wordPrimTyConName   -> check i tc minWord        maxWord-    | tc == int8PrimTyConName   -> check i tc (min' @Int8)   (max' @Int8)-    | tc == int16PrimTyConName  -> check i tc (min' @Int16)  (max' @Int16)-    | tc == int32PrimTyConName  -> check i tc (min' @Int32)  (max' @Int32)-    | tc == int64PrimTyConName  -> check i tc (min' @Int64)  (max' @Int64)-    | tc == word8PrimTyConName  -> check i tc (min' @Word8)  (max' @Word8)-    | tc == word16PrimTyConName -> check i tc (min' @Word16) (max' @Word16)-    | tc == word32PrimTyConName -> check i tc (min' @Word32) (max' @Word32)-    | tc == word64PrimTyConName -> check i tc (min' @Word64) (max' @Word64)+    | sameUnique tc intPrimTyConName    -> check i tc minInt         maxInt+    | sameUnique tc wordPrimTyConName   -> check i tc minWord        maxWord+    | sameUnique tc int8PrimTyConName   -> check i tc (min' @Int8)   (max' @Int8)+    | sameUnique tc int16PrimTyConName  -> check i tc (min' @Int16)  (max' @Int16)+    | sameUnique tc int32PrimTyConName  -> check i tc (min' @Int32)  (max' @Int32)+    | sameUnique tc int64PrimTyConName  -> check i tc (min' @Int64)  (max' @Int64)+    | sameUnique tc word8PrimTyConName  -> check i tc (min' @Word8)  (max' @Word8)+    | sameUnique tc word16PrimTyConName -> check i tc (min' @Word16) (max' @Word16)+    | sameUnique tc word32PrimTyConName -> check i tc (min' @Word32) (max' @Word32)+    | sameUnique tc word64PrimTyConName -> check i tc (min' @Word64) (max' @Word64)      | otherwise -> return () @@ -398,22 +399,22 @@        platform <- targetPlatform <$> getDynFlags          -- Be careful to use target Int/Word sizes! cf #17336-      if | tc == intTyConName     -> case platformWordSize platform of-                                      PW4 -> check @Int32-                                      PW8 -> check @Int64-         | tc == wordTyConName    -> case platformWordSize platform of-                                      PW4 -> check @Word32-                                      PW8 -> check @Word64-         | tc == int8TyConName    -> check @Int8-         | tc == int16TyConName   -> check @Int16-         | tc == int32TyConName   -> check @Int32-         | tc == int64TyConName   -> check @Int64-         | tc == word8TyConName   -> check @Word8-         | tc == word16TyConName  -> check @Word16-         | tc == word32TyConName  -> check @Word32-         | tc == word64TyConName  -> check @Word64-         | tc == integerTyConName -> check @Integer-         | tc == naturalTyConName -> check @Integer+      if | sameUnique tc intTyConName     -> case platformWordSize platform of+                                               PW4 -> check @Int32+                                               PW8 -> check @Int64+         | sameUnique tc wordTyConName    -> case platformWordSize platform of+                                               PW4 -> check @Word32+                                               PW8 -> check @Word64+         | sameUnique tc int8TyConName    -> check @Int8+         | sameUnique tc int16TyConName   -> check @Int16+         | sameUnique tc int32TyConName   -> check @Int32+         | sameUnique tc int64TyConName   -> check @Int64+         | sameUnique tc word8TyConName   -> check @Word8+         | sameUnique tc word16TyConName  -> check @Word16+         | sameUnique tc word32TyConName  -> check @Word32+         | sameUnique tc word64TyConName  -> check @Word64+         | sameUnique tc integerTyConName -> check @Integer+         | sameUnique tc naturalTyConName -> check @Integer             -- We use 'Integer' because otherwise a negative 'Natural' literal             -- could cause a compile time crash (instead of a runtime one).             -- See the T10930b test case for an example of where this matters.
GHC/Linker/Deps.hs view
@@ -1,3 +1,8 @@+-- The transition from Int to Word64 for uniques makes functions slightly larger+-- without this GHC option some optimizations fail to fire.+-- See https://gitlab.haskell.org/ghc/ghc/-/merge_requests/10568#note_505751+{-# OPTIONS_GHC -fspec-constr-threshold=10000 #-}+ {-# LANGUAGE CPP #-} {-# LANGUAGE TupleSections, RecordWildCards #-} {-# LANGUAGE BangPatterns #-}
GHC/Parser/HaddockLex.hs view
@@ -1,7 +1,7 @@ {-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-missing-signatures #-} {-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-}-{-# LINE 1 "_build/source-dist/ghc-9.8.3-src/ghc-9.8.3/compiler/GHC/Parser/HaddockLex.x" #-}+{-# LINE 1 "_build/source-dist/ghc-9.8.4-src/ghc-9.8.4/compiler/GHC/Parser/HaddockLex.x" #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# OPTIONS_GHC -funbox-strict-fields #-}@@ -109,7 +109,7 @@   , (0,alex_action_1)   ] -{-# LINE 86 "_build/source-dist/ghc-9.8.3-src/ghc-9.8.3/compiler/GHC/Parser/HaddockLex.x" #-}+{-# LINE 86 "_build/source-dist/ghc-9.8.4-src/ghc-9.8.4/compiler/GHC/Parser/HaddockLex.x" #-} data AlexInput = AlexInput   { alexInput_position     :: !RealSrcLoc   , alexInput_string       :: !ByteString
GHC/Parser/Lexer.hs view
@@ -1,7 +1,7 @@ {-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-missing-signatures #-} {-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-}-{-# LINE 43 "_build/source-dist/ghc-9.8.3-src/ghc-9.8.3/compiler/GHC/Parser/Lexer.x" #-}+{-# LINE 43 "_build/source-dist/ghc-9.8.4-src/ghc-9.8.4/compiler/GHC/Parser/Lexer.x" #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE LambdaCase #-}@@ -789,7 +789,7 @@   , (0,alex_action_101)   ] -{-# LINE 794 "_build/source-dist/ghc-9.8.3-src/ghc-9.8.3/compiler/GHC/Parser/Lexer.x" #-}+{-# LINE 794 "_build/source-dist/ghc-9.8.4-src/ghc-9.8.4/compiler/GHC/Parser/Lexer.x" #-} -- Operator whitespace occurrence. See Note [Whitespace-sensitive operator parsing]. data OpWs   = OpWsPrefix         -- a !b
GHC/Runtime/Eval.hs view
@@ -325,15 +325,14 @@   | otherwise              = not_tracing  where   tracing-    | EvalBreak is_exception apStack_ref ix mod_uniq resume_ctxt _ccs <- status+    | EvalBreak is_exception apStack_ref ix mod_name resume_ctxt _ccs <- status     , not is_exception     = do        hsc_env <- getSession        let interp = hscInterp hsc_env        let dflags = hsc_dflags hsc_env        let hmi = expectJust "handleRunStatus" $-                   lookupHptDirectly (hsc_HPT hsc_env)-                                     (mkUniqueGrimily mod_uniq)+                   lookupHpt (hsc_HPT hsc_env) (mkModuleName mod_name)            modl = mi_module (hm_iface hmi)            breaks = getModBreaks hmi @@ -358,15 +357,14 @@    not_tracing     -- Hit a breakpoint-    | EvalBreak is_exception apStack_ref ix mod_uniq resume_ctxt ccs <- status+    | EvalBreak is_exception apStack_ref ix mod_name resume_ctxt ccs <- status     = do          hsc_env <- getSession          let interp = hscInterp hsc_env          resume_ctxt_fhv <- liftIO $ mkFinalizedHValue interp resume_ctxt          apStack_fhv <- liftIO $ mkFinalizedHValue interp apStack_ref          let hmi = expectJust "handleRunStatus" $-                     lookupHptDirectly (hsc_HPT hsc_env)-                                       (mkUniqueGrimily mod_uniq)+                     lookupHpt (hsc_HPT hsc_env) (mkModuleName mod_name)              modl = mi_module (hm_iface hmi)              bp | is_exception = Nothing                 | otherwise = Just (BreakInfo modl ix)
GHC/Runtime/Interpreter.hs view
@@ -25,6 +25,7 @@   , mkCostCentres   , costCentreStackInfo   , newBreakArray+  , newModuleName   , storeBreakpoint   , breakpointStatus   , getBreakpointVar@@ -84,7 +85,6 @@ import GHC.Data.Maybe import GHC.Data.FastString -import GHC.Types.Unique import GHC.Types.SrcLoc import GHC.Types.Unique.FM import GHC.Types.Basic@@ -381,6 +381,10 @@   breakArray <- interpCmd interp (NewBreakArray size)   mkFinalizedHValue interp breakArray +newModuleName :: Interp -> ModuleName -> IO (RemotePtr ModuleName)+newModuleName interp mod_name =+  castRemotePtr <$> interpCmd interp (NewBreakModule (moduleNameString mod_name))+ storeBreakpoint :: Interp -> ForeignRef BreakArray -> Int -> Int -> IO () storeBreakpoint interp ref ix cnt = do                               -- #19157   withForeignRef ref $ \breakarray ->@@ -414,13 +418,12 @@ handleSeqHValueStatus :: Interp -> UnitEnv -> EvalStatus () -> IO (EvalResult ()) handleSeqHValueStatus interp unit_env eval_status =   case eval_status of-    (EvalBreak is_exception _ ix mod_uniq resume_ctxt _) -> do+    (EvalBreak is_exception _ ix mod_name resume_ctxt _) -> do       -- A breakpoint was hit; inform the user and tell them       -- which breakpoint was hit.       resume_ctxt_fhv <- liftIO $ mkFinalizedHValue interp resume_ctxt       let hmi = expectJust "handleRunStatus" $-                  lookupHptDirectly (ue_hpt unit_env)-                    (mkUniqueGrimily mod_uniq)+                  lookupHpt (ue_hpt unit_env) (mkModuleName mod_name)           modl = mi_module (hm_iface hmi)           bp | is_exception = Nothing              | otherwise = Just (BreakInfo modl ix)
GHC/Stg/Pipeline.hs view
@@ -58,10 +58,10 @@   deriving (Functor, Applicative, Monad, MonadIO)  instance MonadUnique StgM where-  getUniqueSupplyM = StgM $ do { mask <- ask-                               ; liftIO $! mkSplitUniqSupply mask}-  getUniqueM = StgM $ do { mask <- ask-                         ; liftIO $! uniqFromMask mask}+  getUniqueSupplyM = StgM $ do { tag <- ask+                               ; liftIO $! mkSplitUniqSupply tag}+  getUniqueM = StgM $ do { tag <- ask+                         ; liftIO $! uniqFromTag tag}  runStgM :: Char -> StgM a -> IO a runStgM mask (StgM m) = runReaderT m mask
GHC/StgToByteCode.hs view
@@ -53,7 +53,6 @@ import GHC.Builtin.Types.Prim import GHC.Core.TyCo.Ppr ( pprType ) import GHC.Utils.Error-import GHC.Types.Unique import GHC.Builtin.Uniques import GHC.Data.FastString import GHC.Utils.Panic@@ -392,7 +391,6 @@ schemeER_wrk d p (StgTick (Breakpoint tick_ty tick_no fvs) rhs)   = do  code <- schemeE d 0 p rhs         cc_arr <- getCCArray-        this_mod <- moduleName <$> getCurrentModule         platform <- profilePlatform <$> getProfile         let idOffSets = getVarOffSets platform d p fvs             ty_vars   = tyCoVarsOfTypesWellScoped (tick_ty:map idType fvs)@@ -405,8 +403,12 @@                , interpreterProfiled interp                = cc_arr ! tick_no                | otherwise = toRemotePtr nullPtr-        let breakInstr = BRK_FUN (fromIntegral tick_no) (getUnique this_mod) cc-        return $ breakInstr `consOL` code+        mb_mod_name <- getCurrentModuleName+        case mb_mod_name of+          Just mod_ptr -> do+            let breakInstr = BRK_FUN (fromIntegral tick_no) mod_ptr cc+            return $ breakInstr `consOL` code+          Nothing -> return code schemeER_wrk d p rhs = schemeE d 0 p rhs  getVarOffSets :: Platform -> StackDepth -> BCEnv -> [Id] -> [Maybe (Id, WordOff)]@@ -2263,8 +2265,8 @@ newBreakInfo ix info = BcM $ \st ->   return (st{breakInfo = IntMap.insert ix info (breakInfo st)}, ()) -getCurrentModule :: BcM Module-getCurrentModule = BcM $ \st -> return (st, thisModule st)+getCurrentModuleName :: BcM (Maybe (RemotePtr ModuleName))+getCurrentModuleName = BcM $ \st -> return (st, modBreaks_module <$> modBreaks st)  tickFS :: FastString tickFS = fsLit "ticked"
GHC/StgToCmm/Ticky.hs view
@@ -157,6 +157,7 @@ import GHC.StgToCmm.Env (getCgInfo_maybe) import Data.Coerce (coerce) import GHC.Utils.Json+import GHC.Utils.Unique (anyOfUnique)  ----------------------------------------------------------------------------- --@@ -884,20 +885,19 @@   | otherwise = case tcSplitTyConApp_maybe ty of   Nothing -> '.'   Just (tycon, _) ->-    let anyOf us = getUnique tycon `elem` us in     case () of-      _ | anyOf [fUNTyConKey] -> '>'-        | anyOf [charTyConKey] -> 'C'-        | anyOf [charPrimTyConKey] -> 'c'-        | anyOf [doubleTyConKey] -> 'D'-        | anyOf [doublePrimTyConKey] -> 'd'-        | anyOf [floatTyConKey] -> 'F'-        | anyOf [floatPrimTyConKey] -> 'f'-        | anyOf [intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey] -> 'I'-        | anyOf [intPrimTyConKey, int8PrimTyConKey, int16PrimTyConKey, int32PrimTyConKey, int64PrimTyConKey] -> 'i'-        | anyOf [wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey] -> 'W'-        | anyOf [wordPrimTyConKey, word8PrimTyConKey, word16PrimTyConKey, word32PrimTyConKey, word64PrimTyConKey] -> 'w'-        | anyOf [listTyConKey] -> 'L'+      _ | anyOfUnique tycon [fUNTyConKey] -> '>'+        | anyOfUnique tycon [charTyConKey] -> 'C'+        | anyOfUnique tycon [charPrimTyConKey] -> 'c'+        | anyOfUnique tycon [doubleTyConKey] -> 'D'+        | anyOfUnique tycon [doublePrimTyConKey] -> 'd'+        | anyOfUnique tycon [floatTyConKey] -> 'F'+        | anyOfUnique tycon [floatPrimTyConKey] -> 'f'+        | anyOfUnique tycon [intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey] -> 'I'+        | anyOfUnique tycon [intPrimTyConKey, int8PrimTyConKey, int16PrimTyConKey, int32PrimTyConKey, int64PrimTyConKey] -> 'i'+        | anyOfUnique tycon [wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey] -> 'W'+        | anyOfUnique tycon [wordPrimTyConKey, word8PrimTyConKey, word16PrimTyConKey, word32PrimTyConKey, word64PrimTyConKey] -> 'w'+        | anyOfUnique tycon [listTyConKey] -> 'L'         | isUnboxedTupleTyCon tycon -> 't'         | isTupleTyCon tycon       -> 'T'         | isPrimTyCon tycon        -> 'P'
GHC/StgToJS/Deps.hs view
@@ -45,18 +45,19 @@ import qualified Data.Map as M import qualified Data.Set as S import qualified Data.IntSet as IS-import qualified Data.IntMap as IM-import Data.IntMap (IntMap)+import qualified GHC.Data.Word64Map as WM+import GHC.Data.Word64Map (Word64Map) import Data.Array import Data.Either+import Data.Word import Control.Monad  import Control.Monad.Trans.Class import Control.Monad.Trans.State  data DependencyDataCache = DDC-  { ddcModule :: !(IntMap Unit)        -- ^ Unique Module -> Unit-  , ddcId     :: !(IntMap ExportedFun) -- ^ Unique Id     -> ExportedFun (only to other modules)+  { ddcModule :: !(Word64Map Unit)               -- ^ Unique Module -> Unit+  , ddcId     :: !(Word64Map ExportedFun)        -- ^ Unique Id     -> ExportedFun (only to other modules)   , ddcOther  :: !(Map OtherSymb ExportedFun)   } @@ -71,7 +72,7 @@   -> G BlockInfo genDependencyData mod units = do     ds <- evalStateT (mapM (uncurry oneDep) blocks)-                     (DDC IM.empty IM.empty M.empty)+                     (DDC WM.empty WM.empty M.empty)     return $ BlockInfo       { bi_module     = mod       , bi_must_link  = IS.fromList [ n | (n, _, True, _) <- ds ]@@ -144,7 +145,7 @@             in  if m == mod                    then pprPanic "local id not found" (ppr m)                     else Left <$> do-                            mr <- gets (IM.lookup k . ddcId)+                            mr <- gets (WM.lookup k . ddcId)                             maybe addEntry return mr        -- get the function for an OtherSymb from the cache, add it if necessary@@ -167,7 +168,7 @@        -- lookup a dependency to another module, add to the id cache if there's       -- an id key, otherwise add to other cache-      lookupExternalFun :: Maybe Int+      lookupExternalFun :: Maybe Word64                         -> OtherSymb -> StateT DependencyDataCache G ExportedFun       lookupExternalFun mbIdKey od@(OtherSymb m idTxt) = do         let mk        = getKey . getUnique $ m@@ -175,17 +176,17 @@             exp_fun   = ExportedFun m (LexicalFastString idTxt)             addCache  = do               ms <- gets ddcModule-              let !cache' = IM.insert mk mpk ms+              let !cache' = WM.insert mk mpk ms               modify (\s -> s { ddcModule = cache'})               pure exp_fun         f <- do-          mbm <- gets (IM.member mk . ddcModule)+          mbm <- gets (WM.member mk . ddcModule)           case mbm of             False -> addCache             True  -> pure exp_fun          case mbIdKey of           Nothing -> modify (\s -> s { ddcOther = M.insert od f (ddcOther s) })-          Just k  -> modify (\s -> s { ddcId    = IM.insert k f (ddcId s) })+          Just k  -> modify (\s -> s { ddcId    = WM.insert k f (ddcId s) })          return f
GHC/StgToJS/Ids.hs view
@@ -131,7 +131,7 @@       , if exported           then mempty           else let (c,u) = unpkUnique (getUnique i)-               in mconcat [BSC.pack ['_',c,'_'], intBS u]+               in mconcat [BSC.pack ['_',c,'_'], word64BS u]       ]  -- | Retrieve the cached Ident for the given Id if there is one. Otherwise make
GHC/StgToJS/Symbols.hs view
@@ -8,23 +8,32 @@   , mkFreshJsSymbol   , mkRawSymbol   , intBS+  , word64BS   ) where  import GHC.Prelude  import GHC.Data.FastString import GHC.Unit.Module+import GHC.Utils.Word64 (intToWord64) import Data.ByteString (ByteString)+import Data.Word (Word64) import qualified Data.ByteString.Char8   as BSC import qualified Data.ByteString.Builder as BSB import qualified Data.ByteString.Lazy    as BSL  -- | Hexadecimal representation of an int --+-- Used for the sub indices.+intBS :: Int -> ByteString+intBS = word64BS . intToWord64++-- | Hexadecimal representation of a 64-bit word+-- -- Used for uniques. We could use base-62 as GHC usually does but this is likely -- faster.-intBS :: Int -> ByteString-intBS = BSL.toStrict . BSB.toLazyByteString . BSB.wordHex . fromIntegral+word64BS :: Word64 -> ByteString+word64BS = BSL.toStrict . BSB.toLazyByteString . BSB.word64Hex  -- | Return z-encoded unit:module unitModuleStringZ :: Module -> ByteString
GHC/StgToJS/Types.hs view
@@ -47,6 +47,7 @@ import           Data.Set (Set) import qualified Data.ByteString as BS import           Data.Monoid+import           Data.Word  -- | A State monad over IO holding the generator state. type G = StateT GenState IO@@ -190,7 +191,7 @@  -- | Keys to differentiate Ident's in the ID Cache data IdKey-  = IdKey !Int !Int !IdType+  = IdKey !Word64 !Int !IdType   deriving (Eq, Ord)  -- | Some other symbol
GHC/Tc/Deriv/Utils.hs view
@@ -66,6 +66,7 @@ import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Error+import GHC.Utils.Unique (sameUnique)  import Control.Monad.Trans.Reader import Data.Foldable (traverse_)@@ -893,37 +894,37 @@ -- class for which stock deriving isn't possible. stockSideConditions :: DerivContext -> Class -> Maybe Condition stockSideConditions deriv_ctxt cls-  | cls_key == eqClassKey          = Just (cond_std `andCond` cond_args cls)-  | cls_key == ordClassKey         = Just (cond_std `andCond` cond_args cls)-  | cls_key == showClassKey        = Just (cond_std `andCond` cond_args cls)-  | cls_key == readClassKey        = Just (cond_std `andCond` cond_args cls)-  | cls_key == enumClassKey        = Just (cond_std `andCond` cond_isEnumeration)-  | cls_key == ixClassKey          = Just (cond_std `andCond` cond_enumOrProduct cls)-  | cls_key == boundedClassKey     = Just (cond_std `andCond` cond_enumOrProduct cls)-  | cls_key == dataClassKey        = Just (checkFlag LangExt.DeriveDataTypeable `andCond`-                                           cond_vanilla `andCond`-                                           cond_args cls)-  | cls_key == functorClassKey     = Just (checkFlag LangExt.DeriveFunctor `andCond`-                                           cond_vanilla `andCond`-                                           cond_functorOK True False)-  | cls_key == foldableClassKey    = Just (checkFlag LangExt.DeriveFoldable `andCond`-                                           cond_vanilla `andCond`-                                           cond_functorOK False True)-                                           -- Functor/Fold/Trav works ok-                                           -- for rank-n types-  | cls_key == traversableClassKey = Just (checkFlag LangExt.DeriveTraversable `andCond`-                                           cond_vanilla `andCond`-                                           cond_functorOK False False)-  | cls_key == genClassKey         = Just (checkFlag LangExt.DeriveGeneric `andCond`-                                           cond_vanilla `andCond`-                                           cond_RepresentableOk)-  | cls_key == gen1ClassKey        = Just (checkFlag LangExt.DeriveGeneric `andCond`-                                           cond_vanilla `andCond`-                                           cond_Representable1Ok)-  | cls_key == liftClassKey        = Just (checkFlag LangExt.DeriveLift `andCond`-                                           cond_vanilla `andCond`-                                           cond_args cls)-  | otherwise                      = Nothing+  | sameUnique cls_key eqClassKey          = Just (cond_std `andCond` cond_args cls)+  | sameUnique cls_key ordClassKey         = Just (cond_std `andCond` cond_args cls)+  | sameUnique cls_key showClassKey        = Just (cond_std `andCond` cond_args cls)+  | sameUnique cls_key readClassKey        = Just (cond_std `andCond` cond_args cls)+  | sameUnique cls_key enumClassKey        = Just (cond_std `andCond` cond_isEnumeration)+  | sameUnique cls_key ixClassKey          = Just (cond_std `andCond` cond_enumOrProduct cls)+  | sameUnique cls_key boundedClassKey     = Just (cond_std `andCond` cond_enumOrProduct cls)+  | sameUnique cls_key dataClassKey        = Just (checkFlag LangExt.DeriveDataTypeable `andCond`+                                                   cond_vanilla `andCond`+                                                   cond_args cls)+  | sameUnique cls_key functorClassKey     = Just (checkFlag LangExt.DeriveFunctor `andCond`+                                                   cond_vanilla `andCond`+                                                   cond_functorOK True False)+  | sameUnique cls_key foldableClassKey    = Just (checkFlag LangExt.DeriveFoldable `andCond`+                                                   cond_vanilla `andCond`+                                                   cond_functorOK False True)+                                                   -- Functor/Fold/Trav works ok+                                                   -- for rank-n types+  | sameUnique cls_key traversableClassKey = Just (checkFlag LangExt.DeriveTraversable `andCond`+                                                   cond_vanilla `andCond`+                                                   cond_functorOK False False)+  | sameUnique cls_key genClassKey         = Just (checkFlag LangExt.DeriveGeneric `andCond`+                                                   cond_vanilla `andCond`+                                                   cond_RepresentableOk)+  | sameUnique cls_key gen1ClassKey        = Just (checkFlag LangExt.DeriveGeneric `andCond`+                                                   cond_vanilla `andCond`+                                                   cond_Representable1Ok)+  | sameUnique cls_key liftClassKey        = Just (checkFlag LangExt.DeriveLift `andCond`+                                                   cond_vanilla `andCond`+                                                   cond_args cls)+  | otherwise                        = Nothing   where     cls_key = getUnique cls     cond_std     = cond_stdOK deriv_ctxt False
GHC/Tc/Gen/Foreign.hs view
@@ -71,6 +71,7 @@ import GHC.Utils.Error import GHC.Utils.Outputable as Outputable import GHC.Utils.Panic+import GHC.Utils.Unique import GHC.Platform  import GHC.Data.Bag@@ -741,16 +742,16 @@  boxedMarshalableTyCon :: TyCon -> Validity' TypeCannotBeMarshaledReason boxedMarshalableTyCon tc-   | getUnique tc `elem` [ intTyConKey, int8TyConKey, int16TyConKey-                         , int32TyConKey, int64TyConKey-                         , wordTyConKey, word8TyConKey, word16TyConKey-                         , word32TyConKey, word64TyConKey-                         , floatTyConKey, doubleTyConKey-                         , ptrTyConKey, funPtrTyConKey-                         , charTyConKey-                         , stablePtrTyConKey-                         , boolTyConKey-                         ]+   | anyOfUnique tc [ intTyConKey, int8TyConKey, int16TyConKey+                    , int32TyConKey, int64TyConKey+                    , wordTyConKey, word8TyConKey, word16TyConKey+                    , word32TyConKey, word64TyConKey+                    , floatTyConKey, doubleTyConKey+                    , ptrTyConKey, funPtrTyConKey+                    , charTyConKey+                    , stablePtrTyConKey+                    , boolTyConKey+                    ]   = IsValid    | otherwise = NotValid NotABoxedMarshalableTyCon
GHC/Tc/Types.hs view
@@ -244,7 +244,7 @@                              -- Includes all info about imported things                              -- BangPattern is to fix leak, see #15111 -        env_um   :: {-# UNPACK #-} !Char,   -- Mask for Uniques+        env_ut   :: {-# UNPACK #-} !Char,   -- Tag for Uniques          env_gbl  :: gbl,     -- Info about things defined at the top level                              -- of the module being compiled
GHC/Tc/Types/Origin.hs view
@@ -323,7 +323,7 @@ -- shares a certain 'Unique'. mkSkolemInfo :: MonadIO m => SkolemInfoAnon -> m SkolemInfo mkSkolemInfo sk_anon = do-  u <- liftIO $! uniqFromMask 's'+  u <- liftIO $! uniqFromTag 's'   return (SkolemInfo u sk_anon)  getSkolemInfo :: SkolemInfo -> SkolemInfoAnon
GHC/Tc/Utils/Instantiate.hs view
@@ -90,6 +90,7 @@ import GHC.Utils.Panic import GHC.Utils.Panic.Plain import GHC.Utils.Outputable+import GHC.Utils.Unique (sameUnique)  import GHC.Unit.State import GHC.Unit.External@@ -792,17 +793,17 @@      in hasFixedRuntimeRep_syntactic (FRRArrow $ ArrowFun user_expr) res_ty    mb_arity :: Maybe Arity    mb_arity -- arity of the arrow operation, counting type-level arguments-     | std_nm == arrAName     -- result used as an argument in, e.g., do_premap+     | sameUnique std_nm arrAName     -- result used as an argument in, e.g., do_premap      = Just 3-     | std_nm == composeAName -- result used as an argument in, e.g., dsCmdStmt/BodyStmt+     | sameUnique std_nm composeAName -- result used as an argument in, e.g., dsCmdStmt/BodyStmt      = Just 5-     | std_nm == firstAName   -- result used as an argument in, e.g., dsCmdStmt/BodyStmt+     | sameUnique std_nm firstAName   -- result used as an argument in, e.g., dsCmdStmt/BodyStmt      = Just 4-     | std_nm == appAName     -- result used as an argument in, e.g., dsCmd/HsCmdArrApp/HsHigherOrderApp+     | sameUnique std_nm appAName     -- result used as an argument in, e.g., dsCmd/HsCmdArrApp/HsHigherOrderApp      = Just 2-     | std_nm == choiceAName  -- result used as an argument in, e.g., HsCmdIf+     | sameUnique std_nm choiceAName  -- result used as an argument in, e.g., HsCmdIf      = Just 5-     | std_nm == loopAName    -- result used as an argument in, e.g., HsCmdIf+     | sameUnique std_nm loopAName    -- result used as an argument in, e.g., HsCmdIf      = Just 4      | otherwise      = Nothing
GHC/Tc/Utils/Monad.hs view
@@ -454,14 +454,14 @@ ************************************************************************ -} -initTcRnIf :: Char              -- ^ Mask for unique supply+initTcRnIf :: Char              -- ^ Tag for unique supply            -> HscEnv            -> gbl -> lcl            -> TcRnIf gbl lcl a            -> IO a-initTcRnIf uniq_mask hsc_env gbl_env lcl_env thing_inside+initTcRnIf uniq_tag hsc_env gbl_env lcl_env thing_inside    = do { let { env = Env { env_top = hsc_env,-                            env_um  = uniq_mask,+                            env_ut  = uniq_tag,                             env_gbl = gbl_env,                             env_lcl = lcl_env} } @@ -717,14 +717,14 @@ newUnique :: TcRnIf gbl lcl Unique newUnique  = do { env <- getEnv-      ; let mask = env_um env-      ; liftIO $! uniqFromMask mask }+      ; let tag = env_ut env+      ; liftIO $! uniqFromTag tag }  newUniqueSupply :: TcRnIf gbl lcl UniqSupply newUniqueSupply  = do { env <- getEnv-      ; let mask = env_um env-      ; liftIO $! mkSplitUniqSupply mask }+      ; let tag = env_ut env+      ; liftIO $! mkSplitUniqSupply tag }  cloneLocalName :: Name -> TcM Name -- Make a fresh Internal name with the same OccName and SrcSpan
GHC/ThToHs.hs view
@@ -63,6 +63,7 @@ import Data.List.NonEmpty( NonEmpty (..), nonEmpty ) import qualified Data.List.NonEmpty as NE import Data.Maybe( catMaybes, isNothing )+import Data.Word (Word64) import Language.Haskell.TH as TH hiding (sigP) import Language.Haskell.TH.Syntax as TH import Foreign.ForeignPtr@@ -2199,7 +2200,7 @@ mk_pkg :: TH.PkgName -> Unit mk_pkg pkg = stringToUnit (TH.pkgString pkg) -mk_uniq :: Int -> Unique+mk_uniq :: Word64 -> Unique mk_uniq u = mkUniqueGrimily u  {-
GHC/Types/Name/Cache.hs view
@@ -100,7 +100,7 @@ type OrigNameCache   = ModuleEnv (OccEnv Name)  takeUniqFromNameCache :: NameCache -> IO Unique-takeUniqFromNameCache (NameCache c _) = uniqFromMask c+takeUniqFromNameCache (NameCache c _) = uniqFromTag c  lookupOrigNameCache :: OrigNameCache -> Module -> OccName -> Maybe Name lookupOrigNameCache nc mod occ
GHC/Types/Unique.hs view
@@ -30,9 +30,12 @@          pprUniqueAlways, +        mkTag,         mkUniqueGrimily,+        mkUniqueIntGrimily,         getKey,         mkUnique, unpkUnique,+        mkUniqueInt,         eqUnique, ltUnique,         incrUnique, stepUnique, @@ -52,11 +55,12 @@  import GHC.Data.FastString import GHC.Utils.Outputable-import GHC.Utils.Panic.Plain+import GHC.Utils.Word64 (intToWord64, word64ToInt)  -- just for implementing a fast [0,61) -> Char function import GHC.Exts (indexCharOffAddr#, Char(..), Int(..)) +import GHC.Word         ( Word64 ) import Data.Char        ( chr, ord )  import Language.Haskell.Syntax.Module.Name@@ -68,19 +72,19 @@ *                                                                      * ************************************************************************ -Note [Uniques and masks]+Note [Uniques and tags] ~~~~~~~~~~~~~~~~~~~~~~~~-A `Unique` in GHC is a Word-sized value composed of two pieces:-* A "mask", of width `UNIQUE_TAG_BITS`, in the high order bits-* A number, of width `uNIQUE_BITS`, which fills up the remainder of the Word+A `Unique` in GHC is a 64 bit value composed of two pieces:+* A "tag", of width `UNIQUE_TAG_BITS`, in the high order bits+* A number, of width `uNIQUE_BITS`, which fills up the remainder of the Word64 -The mask is typically an ASCII character.  It is typically used to make it easier+The tag is typically an ASCII character.  It is typically used to make it easier to distinguish uniques constructed by different parts of the compiler.-There is a (potentially incomplete) list of unique masks used given in-GHC.Builtin.Uniques. See Note [Uniques for wired-in prelude things and known masks]+There is a (potentially incomplete) list of unique tags used given in+GHC.Builtin.Uniques. See Note [Uniques for wired-in prelude things and known tags]  `mkUnique` constructs a `Unique` from its pieces-  mkUnique :: Char -> Int -> Unique+  mkUnique :: Char -> Word64 -> Unique  -} @@ -91,24 +95,24 @@ -- the functions from the 'UniqSupply' module -- -- These are sometimes also referred to as \"keys\" in comments in GHC.-newtype Unique = MkUnique Int+newtype Unique = MkUnique Word64  {-# INLINE uNIQUE_BITS #-} uNIQUE_BITS :: Int-uNIQUE_BITS = finiteBitSize (0 :: Int) - UNIQUE_TAG_BITS+uNIQUE_BITS = 64 - UNIQUE_TAG_BITS  {- Now come the functions which construct uniques from their pieces, and vice versa. The stuff about unique *supplies* is handled further down this module. -} -unpkUnique      :: Unique -> (Char, Int)        -- The reverse+unpkUnique      :: Unique -> (Char, Word64)        -- The reverse -mkUniqueGrimily :: Int -> Unique                -- A trap-door for UniqSupply-getKey          :: Unique -> Int                -- for Var+mkUniqueGrimily :: Word64 -> Unique                -- A trap-door for UniqSupply+getKey          :: Unique -> Word64                -- for Var  incrUnique   :: Unique -> Unique-stepUnique   :: Unique -> Int -> Unique+stepUnique   :: Unique -> Word64 -> Unique newTagUnique :: Unique -> Char -> Unique  mkUniqueGrimily = MkUnique@@ -119,7 +123,7 @@ incrUnique (MkUnique i) = MkUnique (i + 1) stepUnique (MkUnique i) n = MkUnique (i + n) -mkLocalUnique :: Int -> Unique+mkLocalUnique :: Word64 -> Unique mkLocalUnique i = mkUnique 'X' i  minLocalUnique :: Unique@@ -131,30 +135,42 @@ -- newTagUnique changes the "domain" of a unique to a different char newTagUnique u c = mkUnique c i where (_,i) = unpkUnique u --- | How many bits are devoted to the unique index (as opposed to the class--- character).-uniqueMask :: Int+-- | Bitmask that has zeros for the tag bits and ones for the rest.+uniqueMask :: Word64 uniqueMask = (1 `shiftL` uNIQUE_BITS) - 1 +-- | Put the character in the highest bits of the Word64.+-- This may truncate the character to UNIQUE_TAG_BITS.+-- This function is used in @`mkSplitUniqSupply`@ so that it can+-- precompute and share the tag part of the uniques it generates.+mkTag :: Char -> Word64+mkTag c = intToWord64 (ord c) `shiftL` uNIQUE_BITS+ -- pop the Char in the top 8 bits of the Unique(Supply)  -- No 64-bit bugs here, as long as we have at least 32 bits. --JSM  -- and as long as the Char fits in 8 bits, which we assume anyway! -mkUnique :: Char -> Int -> Unique       -- Builds a unique from pieces+mkUnique :: Char -> Word64 -> Unique       -- Builds a unique from pieces -- EXPORTED and used only in GHC.Builtin.Uniques mkUnique c i   = MkUnique (tag .|. bits)   where-    tag  = ord c `shiftL` uNIQUE_BITS+    tag  = mkTag c     bits = i .&. uniqueMask +mkUniqueInt :: Char -> Int -> Unique+mkUniqueInt c i = mkUnique c (intToWord64 i)++mkUniqueIntGrimily :: Int -> Unique+mkUniqueIntGrimily = MkUnique . intToWord64+ unpkUnique (MkUnique u)   = let-        -- as long as the Char may have its eighth bit set, we-        -- really do need the logical right-shift here!-        tag = chr (u `shiftR` uNIQUE_BITS)+        -- The potentially truncating use of fromIntegral here is safe+        -- because the argument is just the tag bits after shifting.+        tag = chr (word64ToInt (u `shiftR` uNIQUE_BITS))         i   = u .&. uniqueMask     in     (tag, i)@@ -184,10 +200,10 @@ x `hasKey` k    = getUnique x == k  instance Uniquable FastString where- getUnique fs = mkUniqueGrimily (uniqueOfFS fs)+ getUnique fs = mkUniqueIntGrimily (uniqueOfFS fs)  instance Uniquable Int where- getUnique i = mkUniqueGrimily i+  getUnique i = mkUniqueIntGrimily i  instance Uniquable ModuleName where   getUnique (ModuleName nm) = getUnique nm@@ -261,7 +277,7 @@    1) Use UniqFM or UniqDFM, see Note [Deterministic UniqFM] to decide which   2) Create a newtype wrapper based on Unique ordering where nondeterminism-     is controlled. See Module.ModuleEnv+     is controlled. See GHC.Unit.Module.Env.ModuleEnv   3) Change the algorithm to use nonDetCmpUnique and document why it's still      deterministic   4) Use TrieMap as done in GHC.Cmm.CommonBlockElim.groupByLabel@@ -279,7 +295,7 @@ showUnique :: Unique -> String showUnique uniq   = case unpkUnique uniq of-      (tag, u) -> tag : iToBase62 u+      (tag, u) -> tag : w64ToBase62 u  pprUniqueAlways :: IsLine doc => Unique -> doc -- The "always" means regardless of -dsuppress-uniques@@ -305,19 +321,20 @@ ************************************************************************  A character-stingy way to read/write numbers (notably Uniques).-The ``62-its'' are \tr{[0-9a-zA-Z]}.  We don't handle negative Ints.+The ``62-its'' are \tr{[0-9a-zA-Z]}. Code stolen from Lennart. -} -iToBase62 :: Int -> String-iToBase62 n_-  = assert (n_ >= 0) $ go n_ ""+w64ToBase62 :: Word64 -> String+w64ToBase62 n_ = go n_ ""   where+    -- The potentially truncating uses of fromIntegral here are safe+    -- because the argument is guaranteed to be less than 62 in both cases.     go n cs | n < 62-            = let !c = chooseChar62 n in c : cs+            = let !c = chooseChar62 (word64ToInt n) in c : cs             | otherwise             = go q (c : cs) where (!q, r) = quotRem n 62-                                  !c = chooseChar62 r+                                  !c = chooseChar62 (word64ToInt r)      chooseChar62 :: Int -> Char     {-# INLINE chooseChar62 #-}
GHC/Types/Unique/DFM.hs view
@@ -71,18 +71,18 @@  import GHC.Prelude -import GHC.Types.Unique ( Uniquable(..), Unique, getKey )+import GHC.Types.Unique ( Uniquable(..), Unique, getKey, mkUniqueGrimily ) import GHC.Utils.Outputable -import qualified Data.IntMap.Strict as MS-import qualified Data.IntMap as M+import qualified GHC.Data.Word64Map.Strict as MS+import qualified GHC.Data.Word64Map as M import Data.Data import Data.Functor.Classes (Eq1 (..)) import Data.List (sortBy) import Data.Function (on) import GHC.Types.Unique.FM (UniqFM, nonDetUFMToList, ufmToIntMap, unsafeIntMapToUFM) import Unsafe.Coerce-import qualified Data.IntSet as I+import qualified GHC.Data.Word64Set as W  -- Note [Deterministic UniqFM] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~@@ -147,7 +147,7 @@ -- very much discouraged. data UniqDFM key ele =   UDFM-    !(M.IntMap (TaggedVal ele)) -- A map where keys are Unique's values and+    !(M.Word64Map (TaggedVal ele)) -- A map where keys are Unique's values and                                 -- values are tagged with insertion time.                                 -- The invariant is that all the tags will                                 -- be distinct within a single map@@ -290,6 +290,8 @@ -- | Performs a deterministic fold over the UniqDFM. -- It's O(n log n) while the corresponding function on `UniqFM` is O(n). foldUDFM :: (elt -> a -> a) -> a -> UniqDFM key elt -> a+{-# INLINE foldUDFM #-}+-- This INLINE prevents a regression in !10568 foldUDFM k z m = foldr k z (eltsUDFM m)  -- | Performs a nondeterministic strict fold over the UniqDFM.@@ -306,7 +308,7 @@ -- The INLINE makes it a good producer (from the map) eltsUDFM (UDFM m _i) = map taggedFst (sort_it m) -sort_it :: M.IntMap (TaggedVal elt) -> [TaggedVal elt]+sort_it :: M.Word64Map (TaggedVal elt) -> [TaggedVal elt] sort_it m = sortBy (compare `on` taggedSnd) (M.elems m)  filterUDFM :: (elt -> Bool) -> UniqDFM key elt -> UniqDFM key elt@@ -315,12 +317,12 @@ filterUDFM_Directly :: (Unique -> elt -> Bool) -> UniqDFM key elt -> UniqDFM key elt filterUDFM_Directly p (UDFM m i) = UDFM (M.filterWithKey p' m) i   where-  p' k (TaggedVal v _) = p (getUnique k) v+  p' k (TaggedVal v _) = p (mkUniqueGrimily k) v  udfmRestrictKeys :: UniqDFM key elt -> UniqDFM key elt2 -> UniqDFM key elt udfmRestrictKeys (UDFM a i) (UDFM b _) = UDFM (M.restrictKeys a (M.keysSet b)) i -udfmRestrictKeysSet :: UniqDFM key elt -> I.IntSet -> UniqDFM key elt+udfmRestrictKeysSet :: UniqDFM key elt -> W.Word64Set -> UniqDFM key elt udfmRestrictKeysSet (UDFM val_set i) set =   let key_set = set   in UDFM (M.restrictKeys val_set key_set) i@@ -329,7 +331,7 @@ -- It's O(n log n) while the corresponding function on `UniqFM` is O(n). udfmToList :: UniqDFM key elt -> [(Unique, elt)] udfmToList (UDFM m _i) =-  [ (getUnique k, taggedFst v)+  [ (mkUniqueGrimily k, taggedFst v)   | (k, v) <- sortBy (compare `on` (taggedSnd . snd)) $ M.toList m ]  -- Determines whether two 'UniqDFM's contain the same keys.
GHC/Types/Unique/FM.hs view
@@ -86,12 +86,12 @@  import GHC.Prelude -import GHC.Types.Unique ( Uniquable(..), Unique, getKey )+import GHC.Types.Unique ( Uniquable(..), Unique, getKey, mkUniqueGrimily ) import GHC.Utils.Outputable import GHC.Utils.Panic.Plain-import qualified Data.IntMap as M-import qualified Data.IntMap.Strict as MS-import qualified Data.IntSet as S+import qualified GHC.Data.Word64Map as M+import qualified GHC.Data.Word64Map.Strict as MS+import qualified GHC.Data.Word64Set as S import Data.Data import qualified Data.Semigroup as Semi import Data.Functor.Classes (Eq1 (..))@@ -105,7 +105,7 @@ -- If two types don't overlap in their uniques it's also safe -- to index the same map at multiple key types. But this is -- very much discouraged.-newtype UniqFM key ele = UFM (M.IntMap ele)+newtype UniqFM key ele = UFM (M.Word64Map ele)   deriving (Data, Eq, Functor)   -- Nondeterministic Foldable and Traversable instances are accessible through   -- use of the 'NonDetUniqFM' wrapper.@@ -379,7 +379,7 @@ nonDetFoldWithKeyUFM :: (Unique -> elt -> a -> a) -> a -> UniqFM key elt -> a nonDetFoldWithKeyUFM f z (UFM m) = M.foldrWithKey f' z m   where-    f' k e a = f (getUnique k) e a+    f' k e a = f (mkUniqueGrimily k) e a  mapUFM :: (elt1 -> elt2) -> UniqFM key elt1 -> UniqFM key elt2 mapUFM f (UFM m) = UFM (M.map f m)@@ -388,10 +388,10 @@ mapMaybeUFM f (UFM m) = UFM (M.mapMaybe f m)  mapMaybeWithKeyUFM :: (Unique -> elt1 -> Maybe elt2) -> UniqFM key elt1 -> UniqFM key elt2-mapMaybeWithKeyUFM f (UFM m) = UFM (M.mapMaybeWithKey (f . getUnique) m)+mapMaybeWithKeyUFM f (UFM m) = UFM (M.mapMaybeWithKey (f . mkUniqueGrimily) m)  mapUFM_Directly :: (Unique -> elt1 -> elt2) -> UniqFM key elt1 -> UniqFM key elt2-mapUFM_Directly f (UFM m) = UFM (M.mapWithKey (f . getUnique) m)+mapUFM_Directly f (UFM m) = UFM (M.mapWithKey (f . mkUniqueGrimily) m)  strictMapUFM :: (a -> b) -> UniqFM k a -> UniqFM k b strictMapUFM f (UFM a) = UFM $ MS.map f a@@ -400,7 +400,7 @@ filterUFM p (UFM m) = UFM (M.filter p m)  filterUFM_Directly :: (Unique -> elt -> Bool) -> UniqFM key elt -> UniqFM key elt-filterUFM_Directly p (UFM m) = UFM (M.filterWithKey (p . getUnique) m)+filterUFM_Directly p (UFM m) = UFM (M.filterWithKey (p . mkUniqueGrimily) m)  partitionUFM :: (elt -> Bool) -> UniqFM key elt -> (UniqFM key elt, UniqFM key elt) partitionUFM p (UFM m) =@@ -429,7 +429,7 @@ lookupWithDefaultUFM_Directly :: UniqFM key elt -> elt -> Unique -> elt lookupWithDefaultUFM_Directly (UFM m) v u = M.findWithDefault v (getKey u) m -ufmToSet_Directly :: UniqFM key elt -> S.IntSet+ufmToSet_Directly :: UniqFM key elt -> S.Word64Set ufmToSet_Directly (UFM m) = M.keysSet m  anyUFM :: (elt -> Bool) -> UniqFM key elt -> Bool@@ -451,7 +451,7 @@ -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. nonDetKeysUFM :: UniqFM key elt -> [Unique]-nonDetKeysUFM (UFM m) = map getUnique $ M.keys m+nonDetKeysUFM (UFM m) = map mkUniqueGrimily $ M.keys m  -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce@@ -468,18 +468,18 @@ nonDetStrictFoldUFM_DirectlyM :: (Monad m) => (Unique -> b -> elt -> m b) -> b -> UniqFM key elt -> m b nonDetStrictFoldUFM_DirectlyM f z0 (UFM xs) = M.foldrWithKey c return xs z0   -- See Note [List fusion and continuations in 'c']-  where c u x k z = f (getUnique u) z x >>= k+  where c u x k z = f (mkUniqueGrimily u) z x >>= k         {-# INLINE c #-}  nonDetStrictFoldUFM_Directly:: (Unique -> elt -> a -> a) -> a -> UniqFM key elt -> a-nonDetStrictFoldUFM_Directly k z (UFM m) = M.foldlWithKey' (\z' i x -> k (getUnique i) x z') z m+nonDetStrictFoldUFM_Directly k z (UFM m) = M.foldlWithKey' (\z' i x -> k (mkUniqueGrimily i) x z') z m {-# INLINE nonDetStrictFoldUFM_Directly #-}  -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. nonDetUFMToList :: UniqFM key elt -> [(Unique, elt)]-nonDetUFMToList (UFM m) = map (\(k, v) -> (getUnique k, v)) $ M.toList m+nonDetUFMToList (UFM m) = map (\(k, v) -> (mkUniqueGrimily k, v)) $ M.toList m  -- | A wrapper around 'UniqFM' with the sole purpose of informing call sites -- that the provided 'Foldable' and 'Traversable' instances are@@ -504,10 +504,10 @@ instance forall key. Traversable (NonDetUniqFM key) where   traverse f (NonDetUniqFM (UFM m)) = NonDetUniqFM . UFM <$> traverse f m -ufmToIntMap :: UniqFM key elt -> M.IntMap elt+ufmToIntMap :: UniqFM key elt -> M.Word64Map elt ufmToIntMap (UFM m) = m -unsafeIntMapToUFM :: M.IntMap elt -> UniqFM key elt+unsafeIntMapToUFM :: M.Word64Map elt -> UniqFM key elt unsafeIntMapToUFM = UFM  -- | Cast the key domain of a UniqFM.
GHC/Types/Unique/Supply.hs view
@@ -15,7 +15,7 @@          -- ** Operations on supplies         uniqFromSupply, uniqsFromSupply, -- basic ops-        takeUniqFromSupply, uniqFromMask,+        takeUniqFromSupply, uniqFromTag,          mkSplitUniqSupply,         splitUniqSupply, listSplitUniqSupply,@@ -39,13 +39,20 @@  import GHC.Utils.Monad import Control.Monad-import Data.Char+import Data.Word import GHC.Exts( Ptr(..), noDuplicate#, oneShot )-#if MIN_VERSION_GLASGOW_HASKELL(9,1,0,0)-import GHC.Exts( Int(..), word2Int#, fetchAddWordAddr#, plusWord#, readWordOffAddr# )-#endif import Foreign.Storable +#include "MachDeps.h"++#if MIN_VERSION_GLASGOW_HASKELL(9,1,0,0) && WORD_SIZE_IN_BITS == 64+import GHC.Word( Word64(..) )+import GHC.Exts( fetchAddWordAddr#, plusWord#, readWordOffAddr# )+#if MIN_VERSION_GLASGOW_HASKELL(9,3,0,0)+import GHC.Exts( wordToWord64# )+#endif+#endif+ #include "Unique.h"  {-@@ -61,17 +68,17 @@ The basic idea (due to Lennart Augustsson) is that a UniqSupply is lazily-evaluated infinite tree. -* At each MkSplitUniqSupply node is a unique Int, and two+* At each MkSplitUniqSupply node is a unique Word64, and two   sub-trees (see data UniqSupply)  * takeUniqFromSupply :: UniqSupply -> (Unique, UniqSupply)-  returns the unique Int and one of the sub-trees+  returns the unique Word64 and one of the sub-trees  * splitUniqSupply :: UniqSupply -> (UniqSupply, UniqSupply)   returns the two sub-trees  * When you poke on one of the thunks, it does a foreign call-  to get a fresh Int from a thread-safe counter, and returns+  to get a fresh Word64 from a thread-safe counter, and returns   a fresh MkSplitUniqSupply node.  This has to be as efficient   as possible: it should allocate only      * The fresh node@@ -83,25 +90,25 @@  * For creating new uniques either a UniqSupply is used and threaded through   or for monadic code a MonadUnique instance might conjure up uniques using-  `uniqFromMask`.+  `uniqFromTag`. * Different parts of the compiler will use a UniqSupply or MonadUnique instance-  with a specific mask. This way the different parts of the compiler will-  generate uniques with different masks.+  with a specific tag. This way the different parts of the compiler will+  generate uniques with different tags. -If different code shares the same mask then care has to be taken that all uniques+If different code shares the same tag then care has to be taken that all uniques still get distinct numbers. Usually this is done by relying on genSym which has *one* counter per GHC invocation that is relied on by all calls to it. But using something like the address for pinned objects works as well and in fact is done for fast strings.  This is important for example in the simplifier. Most passes of the simplifier use-the same mask 's'. However in some places we create a unique supply using `mkSplitUniqSupply`+the same tag 's'. However in some places we create a unique supply using `mkSplitUniqSupply` and thread it through the code, while in GHC.Core.Opt.Simplify.Monad  we use the `instance MonadUnique SimplM`, which uses `mkSplitUniqSupply` in getUniqueSupplyM-and `uniqFromMask` in getUniqueM.+and `uniqFromTag` in getUniqueM. -Ultimately all these boil down to each new unique consisting of the mask and the result from-a call to `genSym`. The later producing a distinct number for each invocation ensuring+Ultimately all these boil down to each new unique consisting of the tag and the result from+a call to `genSym`. The latter producing a distinct number for each invocation ensuring uniques are distinct.  Note [Optimising the unique supply]@@ -113,7 +120,7 @@         case unIO genSym s1 of { (# s2, u #) ->         case unIO (unsafeDupableInterleaveIO (IO mk_supply)) s2 of { (# s3, x #) ->         case unIO (unsafeDupableInterleaveIO (IO mk_supply)) s3 of { (# s4, y #) ->-        (# s4, MkSplitUniqSupply (mask .|. u) x y #)+        (# s4, MkSplitUniqSupply (tag .|. u) x y #)         }}}}  It's a classic example of an IO action that is captured and then called@@ -127,7 +134,7 @@                  genSym      >>= \ u ->                  mk_supply   >>= \ s1 ->                  mk_supply   >>= \ s2 ->-                 return (MkSplitUniqSupply (mask .|. u) s1 s2)+                 return (MkSplitUniqSupply (tag .|. u) s1 s2)  and to rely on -fno-state-hack, full laziness and inlining to get the same result. It was very brittle and required enabling -fno-state-hack globally. So@@ -146,29 +153,29 @@ get around the need to allocate one `UniqSupply` for each Unique we need. -For code in IO we can improve on this by threading only the *mask*-we are going to use for Uniques. Using `uniqFromMask` to+For code in IO we can improve on this by threading only the *tag*+we are going to use for Uniques. Using `uniqFromTag` to generate uniques as needed. This gets rid of the overhead of allocating a new UniqSupply for each unique generated. It also avoids-frequent state updates when the Unique/Mask is part of the state in a+frequent state updates when the Unique/Tag is part of the state in a state monad. -For monadic code in IO which always uses the same mask we can go further-and hardcode the mask into the MonadUnique instance. On top of all the-benefits of threading the mask this *also* has the benefit of avoiding-the mask getting captured in thunks, or being passed around at runtime.-It does however come at the cost of having to use a fixed Mask for all-code run in this Monad. But remember, the Mask is purely cosmetic:-See Note [Uniques and masks].+For monadic code in IO which always uses the same tag we can go further+and hardcode the tag into the MonadUnique instance. On top of all the+benefits of threading the tag this *also* has the benefit of avoiding+the tag getting captured in thunks, or being passed around at runtime.+It does however come at the cost of having to use a fixed tag for all+code run in this Monad. But remember, the tag is purely cosmetic:+See Note [Uniques and tags].  NB: It's *not* an optimization to pass around the UniqSupply inside an-IORef instead of the mask. While this would avoid frequent state updates+IORef instead of the tag. While this would avoid frequent state updates it still requires allocating one UniqSupply per Unique. On top of some overhead for reading/writing to/from the IORef.  All of this hinges on the assumption that UniqSupply and-uniqFromMask use the same source of distinct numbers (`genSym`) which-allows both to be used at the same time, with the same mask, while still+uniqFromTag use the same source of distinct numbers (`genSym`) which+allows both to be used at the same time, with the same tag, while still ensuring distinct uniques. One might consider this fact to be an "accident". But GHC worked like this as far back as source control history goes. It also allows the later two@@ -184,18 +191,18 @@ -- also manufacture an arbitrary number of further 'UniqueSupply' values, -- which will be distinct from the first and from all others. data UniqSupply-  = MkSplitUniqSupply {-# UNPACK #-} !Int -- make the Unique with this+  = MkSplitUniqSupply {-# UNPACK #-} !Word64 -- make the Unique with this                    UniqSupply UniqSupply                                 -- when split => these two supplies  mkSplitUniqSupply :: Char -> IO UniqSupply -- ^ Create a unique supply out of thin air.--- The "mask" (Char) supplied is purely cosmetic, making it easier+-- The "tag" (Char) supplied is purely cosmetic, making it easier -- to figure out where a Unique was born. See--- Note [Uniques and masks].+-- Note [Uniques and tags]. -- -- The payload part of the Uniques allocated from this UniqSupply are--- guaranteed distinct wrt all other supplies, regardless of their "mask".+-- guaranteed distinct wrt all other supplies, regardless of their "tag". -- This is achieved by allocating the payload part from -- a single source of Uniques, namely `genSym`, shared across -- all UniqSupply's.@@ -206,7 +213,7 @@   = unsafeDupableInterleaveIO (IO mk_supply)    where-     !mask = ord c `unsafeShiftL` uNIQUE_BITS+     !tag = mkTag c          -- Here comes THE MAGIC: see Note [How the unique supply works]         -- This is one of the most hammered bits in the whole compiler@@ -218,21 +225,28 @@         -- deferred IO computations         case unIO (unsafeDupableInterleaveIO (IO mk_supply)) s2 of { (# s3, x #) ->         case unIO (unsafeDupableInterleaveIO (IO mk_supply)) s3 of { (# s4, y #) ->-        (# s4, MkSplitUniqSupply (mask .|. u) x y #)+        (# s4, MkSplitUniqSupply (tag .|. u) x y #)         }}}} -#if !MIN_VERSION_GLASGOW_HASKELL(9,1,0,0)-foreign import ccall unsafe "genSym" genSym :: IO Int+-- If a word is not 64 bits then we would need a fetchAddWord64Addr# primitive,+-- which does not exist. So we fall back on the C implementation in that case.++#if !MIN_VERSION_GLASGOW_HASKELL(9,1,0,0) || WORD_SIZE_IN_BITS != 64+foreign import ccall unsafe "genSym" genSym :: IO Word64 #else-genSym :: IO Int+genSym :: IO Word64 genSym = do     let !mask = (1 `unsafeShiftL` uNIQUE_BITS) - 1-    let !(Ptr counter) = ghc_unique_counter+    let !(Ptr counter) = ghc_unique_counter64     let !(Ptr inc_ptr) = ghc_unique_inc     u <- IO $ \s0 -> case readWordOffAddr# inc_ptr 0# s0 of         (# s1, inc #) -> case fetchAddWordAddr# counter inc s1 of             (# s2, val #) ->-                let !u = I# (word2Int# (val `plusWord#` inc)) .&. mask+#if !MIN_VERSION_GLASGOW_HASKELL(9,3,0,0)+                let !u = W64# (val `plusWord#` inc) .&. mask+#else+                let !u = W64# (wordToWord64# (val `plusWord#` inc)) .&. mask+#endif                 in (# s2, u #) #if defined(DEBUG)     -- Uh oh! We will overflow next time a unique is requested.@@ -242,19 +256,19 @@     return u #endif -foreign import ccall unsafe "&ghc_unique_counter" ghc_unique_counter :: Ptr Word-foreign import ccall unsafe "&ghc_unique_inc"     ghc_unique_inc     :: Ptr Int+foreign import ccall unsafe "&ghc_unique_counter64" ghc_unique_counter64 :: Ptr Word64+foreign import ccall unsafe "&ghc_unique_inc"       ghc_unique_inc       :: Ptr Int -initUniqSupply :: Word -> Int -> IO ()+initUniqSupply :: Word64 -> Int -> IO () initUniqSupply counter inc = do-    poke ghc_unique_counter counter-    poke ghc_unique_inc     inc+    poke ghc_unique_counter64 counter+    poke ghc_unique_inc       inc -uniqFromMask :: Char -> IO Unique-uniqFromMask !mask+uniqFromTag :: Char -> IO Unique+uniqFromTag !tag   = do { uqNum <- genSym-       ; return $! mkUnique mask uqNum }-{-# NOINLINE uniqFromMask #-} -- We'll unbox everything, but we don't want to inline it+       ; return $! mkUnique tag uqNum }+{-# NOINLINE uniqFromTag #-} -- We'll unbox everything, but we don't want to inline it  splitUniqSupply :: UniqSupply -> (UniqSupply, UniqSupply) -- ^ Build two 'UniqSupply' from a single one, each of which
GHC/Types/Var.hs view
@@ -117,7 +117,7 @@ import {-# SOURCE #-}   GHC.Builtin.Types ( manyDataConTy ) import GHC.Types.Name hiding (varName) import GHC.Types.Unique ( Uniquable, Unique, getKey, getUnique-                        , mkUniqueGrimily, nonDetCmpUnique )+                        , nonDetCmpUnique ) import GHC.Types.Basic( TypeOrConstraint(..) ) import GHC.Utils.Misc import GHC.Utils.Binary@@ -247,7 +247,7 @@   = TyVar {  -- Type and kind variables              -- see Note [Kind and type variables]         varName    :: !Name,-        realUnique :: {-# UNPACK #-} !Int,+        realUnique :: {-# UNPACK #-} !Unique,                                      -- ^ Key for fast comparison                                      -- Identical to the Unique in the name,                                      -- cached here for speed@@ -258,14 +258,14 @@                                         -- Used for kind variables during                                         -- inference, as well         varName        :: !Name,-        realUnique     :: {-# UNPACK #-} !Int,+        realUnique     :: {-# UNPACK #-} !Unique,         varType        :: Kind,         tc_tv_details  :: TcTyVarDetails   }    | Id {         varName    :: !Name,-        realUnique :: {-# UNPACK #-} !Int,+        realUnique :: {-# UNPACK #-} !Unique,         varType    :: Type,         varMult    :: Mult,             -- See Note [Multiplicity of let binders]         idScope    :: IdScope,@@ -374,10 +374,10 @@     a == b = realUnique a == realUnique b  instance Ord Var where-    a <= b = realUnique a <= realUnique b-    a <  b = realUnique a <  realUnique b-    a >= b = realUnique a >= realUnique b-    a >  b = realUnique a >  realUnique b+    a <= b = getKey (realUnique a) <= getKey (realUnique b)+    a <  b = getKey (realUnique a) <  getKey (realUnique b)+    a >= b = getKey (realUnique a) >= getKey (realUnique b)+    a >  b = getKey (realUnique a) >  getKey (realUnique b)     a `compare` b = a `nonDetCmpVar` b  -- | Compare Vars by their Uniques.@@ -397,7 +397,7 @@   occName = nameOccName . varName  varUnique :: Var -> Unique-varUnique var = mkUniqueGrimily (realUnique var)+varUnique var = realUnique var  varMultMaybe :: Id -> Maybe Mult varMultMaybe (Id { varMult = mult }) = Just mult@@ -405,12 +405,12 @@  setVarUnique :: Var -> Unique -> Var setVarUnique var uniq-  = var { realUnique = getKey uniq,+  = var { realUnique = uniq,           varName = setNameUnique (varName var) uniq }  setVarName :: Var -> Name -> Var setVarName var new_name-  = var { realUnique = getKey (getUnique new_name),+  = var { realUnique = getUnique new_name,           varName = new_name }  setVarType :: Var -> Type -> Var@@ -1080,7 +1080,7 @@  mkTyVar :: Name -> Kind -> TyVar mkTyVar name kind = TyVar { varName    = name-                          , realUnique = getKey (nameUnique name)+                          , realUnique = nameUnique name                           , varType  = kind                           } @@ -1088,7 +1088,7 @@ mkTcTyVar name kind details   = -- NB: 'kind' may be a coercion kind; cf, 'GHC.Tc.Utils.TcMType.newMetaCoVar'     TcTyVar {   varName    = name,-                realUnique = getKey (nameUnique name),+                realUnique = nameUnique name,                 varType  = kind,                 tc_tv_details = details         }@@ -1144,7 +1144,7 @@ mk_id :: Name -> Mult -> Type -> IdScope -> IdDetails -> IdInfo -> Id mk_id name !w ty scope details info   = Id { varName    = name,-         realUnique = getKey (nameUnique name),+         realUnique = nameUnique name,          varMult    = w,          varType    = ty,          idScope    = scope,
GHC/Types/Var/Env.hs view
@@ -78,7 +78,7 @@     ) where  import GHC.Prelude-import qualified Data.IntMap.Strict as IntMap -- TODO: Move this to UniqFM+import qualified GHC.Data.Word64Map.Strict as Word64Map -- TODO: Move this to UniqFM  import GHC.Types.Name.Occurrence import GHC.Types.Name@@ -228,7 +228,7 @@ -- introduce non-unique 'Unique's this way. See Note [Local uniques]. unsafeGetFreshLocalUnique :: InScopeSet -> Unique unsafeGetFreshLocalUnique (InScope set)-  | Just (uniq,_) <- IntMap.lookupLT (getKey maxLocalUnique) (ufmToIntMap $ getUniqSet set)+  | Just (uniq,_) <- Word64Map.lookupLT (getKey maxLocalUnique) (ufmToIntMap $ getUniqSet set)   , let uniq' = mkLocalUnique uniq   , not $ uniq' `ltUnique` minLocalUnique   = incrUnique uniq'
+ GHC/Utils/Containers/Internal/BitUtil.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__+{-# LANGUAGE MagicHash #-}+#endif+#if !defined(TESTING) && defined(__GLASGOW_HASKELL__)+{-# LANGUAGE Safe #-}+#endif++#include "containers.h"++-----------------------------------------------------------------------------+-- |+-- Module      :  Utils.Containers.Internal.BitUtil+-- Copyright   :  (c) Clark Gaebel 2012+--                (c) Johan Tibel 2012+-- License     :  BSD-style+-- Maintainer  :  libraries@haskell.org+-- Portability :  portable+-----------------------------------------------------------------------------+--+-- = WARNING+--+-- This module is considered __internal__.+--+-- The Package Versioning Policy __does not apply__.+--+-- The contents of this module may change __in any way whatsoever__+-- and __without any warning__ between minor versions of this package.+--+-- Authors importing this module are expected to track development+-- closely.++module GHC.Utils.Containers.Internal.BitUtil+    ( bitcount+    , highestBitMask+    , shiftLL+    , shiftRL+    ) where++import GHC.Prelude.Basic+import Data.Word++{----------------------------------------------------------------------+  [bitcount] as posted by David F. Place to haskell-cafe on April 11, 2006,+  based on the code on+  http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan,+  where the following source is given:+    Published in 1988, the C Programming Language 2nd Ed. (by Brian W.+    Kernighan and Dennis M. Ritchie) mentions this in exercise 2-9. On April+    19, 2006 Don Knuth pointed out to me that this method "was first published+    by Peter Wegner in CACM 3 (1960), 322. (Also discovered independently by+    Derrick Lehmer and published in 1964 in a book edited by Beckenbach.)"+----------------------------------------------------------------------}++bitcount :: Int -> Word64 -> Int+bitcount a x = a + popCount x+{-# INLINE bitcount #-}++-- The highestBitMask implementation is based on+-- http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2+-- which has been put in the public domain.++-- | Return a word where only the highest bit is set.+highestBitMask :: Word64 -> Word64+highestBitMask w = shiftLL 1 (63 - countLeadingZeros w)+{-# INLINE highestBitMask #-}++-- Right and left logical shifts.+shiftRL, shiftLL :: Word64 -> Int -> Word64+shiftRL = unsafeShiftR+shiftLL = unsafeShiftL
+ GHC/Utils/Containers/Internal/StrictPair.hs view
@@ -0,0 +1,24 @@+{-# LANGUAGE CPP #-}+#if !defined(TESTING) && defined(__GLASGOW_HASKELL__)+{-# LANGUAGE Safe #-}+#endif++#include "containers.h"++-- | A strict pair++module GHC.Utils.Containers.Internal.StrictPair (StrictPair(..), toPair) where++-- | The same as a regular Haskell pair, but+--+-- @+-- (x :*: _|_) = (_|_ :*: y) = _|_+-- @+data StrictPair a b = !a :*: !b++infixr 1 :*:++-- | Convert a strict pair to a standard pair.+toPair :: StrictPair a b -> (a, b)+toPair (x :*: y) = (x, y)+{-# INLINE toPair #-}
GHC/Utils/Outputable.hs view
@@ -37,7 +37,7 @@         spaceIfSingleQuote,         isEmpty, nest,         ptext,-        int, intWithCommas, integer, word, float, double, rational, doublePrec,+        int, intWithCommas, integer, word64, word, float, double, rational, doublePrec,         parens, cparen, brackets, braces, quotes, quote,         doubleQuotes, angleBrackets,         semi, comma, colon, dcolon, space, equals, dot, vbar,@@ -142,7 +142,7 @@ import qualified Data.IntMap as IM import Data.Set (Set) import qualified Data.Set as Set-import qualified Data.IntSet as IntSet+import qualified GHC.Data.Word64Set as Word64Set import Data.String import Data.Word import System.IO        ( Handle )@@ -682,6 +682,7 @@ int      :: IsLine doc => Int        -> doc integer  :: IsLine doc => Integer    -> doc word     ::               Integer    -> SDoc+word64   :: IsLine doc => Word64     -> doc float    :: IsLine doc => Float      -> doc double   :: IsLine doc => Double     -> doc rational ::               Rational   -> SDoc@@ -699,6 +700,8 @@ {-# INLINE CONLIKE rational #-} rational n  = text $ show n               -- See Note [Print Hexadecimal Literals] in GHC.Utils.Ppr+{-# INLINE CONLIKE word64 #-}+word64 n    = text $ show n {-# INLINE CONLIKE word #-} word n      = sdocOption sdocHexWordLiterals $ \case                True  -> docToSDoc $ Pretty.hex n@@ -976,8 +979,8 @@ instance (Outputable a) => Outputable (Set a) where     ppr s = braces (pprWithCommas ppr (Set.toList s)) -instance Outputable IntSet.IntSet where-    ppr s = braces (pprWithCommas ppr (IntSet.toList s))+instance Outputable Word64Set.Word64Set where+    ppr s = braces (pprWithCommas ppr (Word64Set.toList s))  instance (Outputable a, Outputable b) => Outputable (a, b) where     ppr (x,y) = parens (sep [ppr x <> comma, ppr y])
+ GHC/Utils/Unique.hs view
@@ -0,0 +1,35 @@+{-# LANGUAGE CPP #-}++{- Work around #23537++On 32 bit systems, GHC's codegen around 64 bit numbers is not quite+complete. This led to panics mentioning missing cases in iselExpr64.+Now that GHC uses Word64 for its uniques, these panics have started+popping up whenever a unique is compared to many other uniques in one+function. As a workaround we use these two functions which are not+inlined on 32 bit systems, thus preventing the panics.+-}++module GHC.Utils.Unique (sameUnique, anyOfUnique) where++#include "MachDeps.h"++import GHC.Prelude.Basic (Bool, Eq((==)), Foldable(elem))+import GHC.Types.Unique (Unique, Uniquable (getUnique))+++#if WORD_SIZE_IN_BITS == 32+{-# NOINLINE sameUnique #-}+#else+{-# INLINE sameUnique #-}+#endif+sameUnique :: Uniquable a => a -> a -> Bool+sameUnique x y = getUnique x == getUnique y++#if WORD_SIZE_IN_BITS == 32+{-# NOINLINE anyOfUnique #-}+#else+{-# INLINE anyOfUnique #-}+#endif+anyOfUnique :: Uniquable a => a -> [Unique] -> Bool+anyOfUnique tc xs = getUnique tc `elem` xs
+ GHC/Utils/Word64.hs view
@@ -0,0 +1,20 @@+module GHC.Utils.Word64 (+    intToWord64,+    word64ToInt,+    truncateWord64ToWord32,+  ) where++import GHC.Prelude+import GHC.Utils.Panic.Plain (assert)++import Data.Word+import GHC.Stack++intToWord64 :: HasCallStack => Int -> Word64+intToWord64 x = assert (0 <= x) (fromIntegral x)++word64ToInt :: HasCallStack => Word64 -> Int+word64ToInt x = assert (x <= fromIntegral (maxBound :: Int)) (fromIntegral x)++truncateWord64ToWord32 :: Word64 -> Word32+truncateWord64ToWord32 = fromIntegral
cbits/genSym.c view
@@ -9,16 +9,32 @@ // // The CPP is thus about the RTS version GHC is linked against, and not the // version of the GHC being built.+#if !MIN_VERSION_GLASGOW_HASKELL(9,8,4,0)+HsWord64 ghc_unique_counter64 = 0;+#endif #if !MIN_VERSION_GLASGOW_HASKELL(9,3,0,0)-HsInt ghc_unique_counter = 0; HsInt ghc_unique_inc     = 1; #endif -#define UNIQUE_BITS (sizeof (HsInt) * 8 - UNIQUE_TAG_BITS)+// This function has been added to the RTS. Here we pessimistically assume+// that a threaded RTS is used. This function is only used for bootstrapping.+#if !MIN_VERSION_GLASGOW_HASKELL(9,7,0,0)+EXTERN_INLINE StgWord64+atomic_inc64(StgWord64 volatile* p, StgWord64 incr)+{+#if defined(HAVE_C11_ATOMICS)+    return __atomic_add_fetch(p, incr, __ATOMIC_SEQ_CST);+#else+    return __sync_add_and_fetch(p, incr);+#endif+}+#endif++#define UNIQUE_BITS (sizeof (HsWord64) * 8 - UNIQUE_TAG_BITS) #define UNIQUE_MASK ((1ULL << UNIQUE_BITS) - 1) -HsInt genSym(void) {-    HsInt u = atomic_inc((StgWord *)&ghc_unique_counter, ghc_unique_inc) & UNIQUE_MASK;+HsWord64 genSym(void) {+    HsWord64 u = atomic_inc64((StgWord64 *)&ghc_unique_counter64, ghc_unique_inc) & UNIQUE_MASK;     // Uh oh! We will overflow next time a unique is requested.     ASSERT(u != UNIQUE_MASK);     return u;
ghc.cabal view
@@ -3,7 +3,7 @@ -- ./configure.  Make sure you are editing ghc.cabal.in, not ghc.cabal.  Name: ghc-Version: 9.8.3+Version: 9.8.4 License: BSD-3-Clause License-File: LICENSE Author: The GHC Team@@ -110,9 +110,9 @@                    exceptions == 0.10.*,                    semaphore-compat,                    stm,-                   ghc-boot   == 9.8.3,-                   ghc-heap   == 9.8.3,-                   ghci == 9.8.3+                   ghc-boot   == 9.8.4,+                   ghc-heap   == 9.8.4,+                   ghci == 9.8.4      if os(windows)         Build-Depends: Win32  >= 2.3 && < 2.14@@ -165,7 +165,11 @@         -- as it's magic.         GHC-Options: -this-unit-id ghc -    c-sources:+    if arch(javascript)+      js-sources:+        jsbits/genSym.js+    else+      c-sources:         cbits/cutils.c         cbits/genSym.c         cbits/keepCAFsForGHCi.c@@ -417,6 +421,13 @@         GHC.Data.TrieMap         GHC.Data.Unboxed         GHC.Data.UnionFind+        GHC.Data.Word64Set+        GHC.Data.Word64Set.Internal+        GHC.Data.Word64Map+        GHC.Data.Word64Map.Internal+        GHC.Data.Word64Map.Lazy+        GHC.Data.Word64Map.Strict+        GHC.Data.Word64Map.Strict.Internal         GHC.Driver.Backend         GHC.Driver.Backend.Internal         GHC.Driver.Backpack@@ -884,6 +895,8 @@         GHC.Utils.BufHandle         GHC.Utils.CliOption         GHC.Utils.Constants+        GHC.Utils.Containers.Internal.BitUtil+        GHC.Utils.Containers.Internal.StrictPair         GHC.Utils.Error         GHC.Utils.Exception         GHC.Utils.Fingerprint@@ -904,6 +917,8 @@         GHC.Utils.Ppr.Colour         GHC.Utils.TmpFs         GHC.Utils.Trace+        GHC.Utils.Unique+        GHC.Utils.Word64         GHC.Wasm.ControlFlow         GHC.Wasm.ControlFlow.FromCmm         GHC.CmmToAsm.Wasm
+ jsbits/genSym.js view
@@ -0,0 +1,26 @@+//#OPTIONS: CPP+#include "Unique.h"++// We assume that the unique tag occupies less than 32 bits (should be safe)+#define HIGH_UNIQUE_BITS (32 - UNIQUE_TAG_BITS)+#define HIGH_UNIQUE_MASK ((1 << HIGH_UNIQUE_BITS) - 1)++// The 'ghc_unique_inc' and 'ghc_unique_counter64' are in the native RTS. It allows them to be+// shared with plugins even if two different instances of the GHC library are+// loaded at the same time (#19940)+// However, cross compilers do not support plugins so we have moved these globals back+// into the compiler.+var h$ghc_unique_inc       = h$newByteArray(4);+h$ghc_unique_inc.i3[0]     = 1;+var h$ghc_unique_counter64   = h$newByteArray(8);+h$ghc_unique_counter64.i3[0] = 0;+h$ghc_unique_counter64.i3[1] = 0;++function h$genSym() {+  var rl = h$hs_plusWord64(h$ghc_unique_counter64.i3[1] >>> 0, h$ghc_unique_counter64.i3[0] >>> 0, 0, h$ghc_unique_inc.i3[0] >>> 0);+  h$ret1 = (h$ret1 & HIGH_UNIQUE_MASK) >>> 0;+  // h$ret1 contains the higher part (rh)+  h$ghc_unique_counter64.i3[0] = rl | 0;+  h$ghc_unique_counter64.i3[1] = h$ret1 | 0;+  return rl; // h$ret1 still contains rh+}