packages feed

uulib 0.9.10 → 0.9.11

raw patch · 11 files changed

+128/−6226 lines, 11 filesnew-uploaderPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- UU.DData.IntBag: (\\) :: IntBag -> IntBag -> IntBag
- UU.DData.IntBag: data IntBag
- UU.DData.IntBag: delete :: Int -> IntBag -> IntBag
- UU.DData.IntBag: deleteAll :: Int -> IntBag -> IntBag
- UU.DData.IntBag: difference :: IntBag -> IntBag -> IntBag
- UU.DData.IntBag: distinctSize :: IntBag -> Int
- UU.DData.IntBag: elems :: IntBag -> [Int]
- UU.DData.IntBag: empty :: IntBag
- UU.DData.IntBag: filter :: (Int -> Bool) -> IntBag -> IntBag
- UU.DData.IntBag: fold :: (Int -> b -> b) -> b -> IntBag -> b
- UU.DData.IntBag: foldOccur :: (Int -> Int -> b -> b) -> b -> IntBag -> b
- UU.DData.IntBag: fromAscList :: [Int] -> IntBag
- UU.DData.IntBag: fromAscOccurList :: [(Int, Int)] -> IntBag
- UU.DData.IntBag: fromDistinctAscList :: [Int] -> IntBag
- UU.DData.IntBag: fromList :: [Int] -> IntBag
- UU.DData.IntBag: fromMap :: IntMap Int -> IntBag
- UU.DData.IntBag: fromOccurList :: [(Int, Int)] -> IntBag
- UU.DData.IntBag: fromOccurMap :: IntMap Int -> IntBag
- UU.DData.IntBag: insert :: Int -> IntBag -> IntBag
- UU.DData.IntBag: insertMany :: Int -> Int -> IntBag -> IntBag
- UU.DData.IntBag: instance Eq IntBag
- UU.DData.IntBag: instance Show IntBag
- UU.DData.IntBag: intersection :: IntBag -> IntBag -> IntBag
- UU.DData.IntBag: isEmpty :: IntBag -> Bool
- UU.DData.IntBag: member :: Int -> IntBag -> Bool
- UU.DData.IntBag: occur :: Int -> IntBag -> Int
- UU.DData.IntBag: partition :: (Int -> Bool) -> IntBag -> (IntBag, IntBag)
- UU.DData.IntBag: properSubset :: IntBag -> IntBag -> Bool
- UU.DData.IntBag: showTree :: IntBag -> String
- UU.DData.IntBag: showTreeWith :: Bool -> Bool -> IntBag -> String
- UU.DData.IntBag: single :: Int -> IntBag
- UU.DData.IntBag: size :: IntBag -> Int
- UU.DData.IntBag: subset :: IntBag -> IntBag -> Bool
- UU.DData.IntBag: toAscList :: IntBag -> [Int]
- UU.DData.IntBag: toAscOccurList :: IntBag -> [(Int, Int)]
- UU.DData.IntBag: toList :: IntBag -> [Int]
- UU.DData.IntBag: toMap :: IntBag -> IntMap Int
- UU.DData.IntBag: toOccurList :: IntBag -> [(Int, Int)]
- UU.DData.IntBag: union :: IntBag -> IntBag -> IntBag
- UU.DData.IntBag: unions :: [IntBag] -> IntBag
- UU.DData.IntMap: (!) :: IntMap a -> Key -> a
- UU.DData.IntMap: (\\) :: IntMap a -> IntMap a -> IntMap a
- UU.DData.IntMap: adjust :: (a -> a) -> Key -> IntMap a -> IntMap a
- UU.DData.IntMap: adjustWithKey :: (Key -> a -> a) -> Key -> IntMap a -> IntMap a
- UU.DData.IntMap: assocs :: IntMap a -> [(Key, a)]
- UU.DData.IntMap: data IntMap a
- UU.DData.IntMap: delete :: Key -> IntMap a -> IntMap a
- UU.DData.IntMap: difference :: IntMap a -> IntMap a -> IntMap a
- UU.DData.IntMap: differenceWith :: (a -> a -> Maybe a) -> IntMap a -> IntMap a -> IntMap a
- UU.DData.IntMap: differenceWithKey :: (Key -> a -> a -> Maybe a) -> IntMap a -> IntMap a -> IntMap a
- UU.DData.IntMap: elems :: IntMap a -> [a]
- UU.DData.IntMap: empty :: IntMap a
- UU.DData.IntMap: filter :: (a -> Bool) -> IntMap a -> IntMap a
- UU.DData.IntMap: filterWithKey :: (Key -> a -> Bool) -> IntMap a -> IntMap a
- UU.DData.IntMap: find :: Key -> IntMap a -> a
- UU.DData.IntMap: findWithDefault :: a -> Key -> IntMap a -> a
- UU.DData.IntMap: fold :: (a -> b -> b) -> b -> IntMap a -> b
- UU.DData.IntMap: foldWithKey :: (Key -> a -> b -> b) -> b -> IntMap a -> b
- UU.DData.IntMap: fromAscList :: [(Key, a)] -> IntMap a
- UU.DData.IntMap: fromAscListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a
- UU.DData.IntMap: fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a
- UU.DData.IntMap: fromDistinctAscList :: [(Key, a)] -> IntMap a
- UU.DData.IntMap: fromList :: [(Key, a)] -> IntMap a
- UU.DData.IntMap: fromListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a
- UU.DData.IntMap: fromListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a
- UU.DData.IntMap: insert :: Key -> a -> IntMap a -> IntMap a
- UU.DData.IntMap: insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> (Maybe a, IntMap a)
- UU.DData.IntMap: insertWith :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a
- UU.DData.IntMap: insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> IntMap a
- UU.DData.IntMap: instance (Eq a) => Eq (IntMap a)
- UU.DData.IntMap: instance (Show a) => Show (IntMap a)
- UU.DData.IntMap: intersection :: IntMap a -> IntMap a -> IntMap a
- UU.DData.IntMap: intersectionWith :: (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
- UU.DData.IntMap: intersectionWithKey :: (Key -> a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
- UU.DData.IntMap: isEmpty :: IntMap a -> Bool
- UU.DData.IntMap: keys :: IntMap a -> [Key]
- UU.DData.IntMap: lookup :: Key -> IntMap a -> Maybe a
- UU.DData.IntMap: map :: (a -> b) -> IntMap a -> IntMap b
- UU.DData.IntMap: mapAccum :: (a -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)
- UU.DData.IntMap: mapAccumWithKey :: (a -> Key -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)
- UU.DData.IntMap: mapWithKey :: (Key -> a -> b) -> IntMap a -> IntMap b
- UU.DData.IntMap: member :: Key -> IntMap a -> Bool
- UU.DData.IntMap: partition :: (a -> Bool) -> IntMap a -> (IntMap a, IntMap a)
- UU.DData.IntMap: partitionWithKey :: (Key -> a -> Bool) -> IntMap a -> (IntMap a, IntMap a)
- UU.DData.IntMap: properSubset :: (Eq a) => IntMap a -> IntMap a -> Bool
- UU.DData.IntMap: properSubsetBy :: (a -> a -> Bool) -> IntMap a -> IntMap a -> Bool
- UU.DData.IntMap: showTree :: (Show a) => IntMap a -> String
- UU.DData.IntMap: showTreeWith :: (Show a) => Bool -> Bool -> IntMap a -> String
- UU.DData.IntMap: single :: Key -> a -> IntMap a
- UU.DData.IntMap: size :: IntMap a -> Int
- UU.DData.IntMap: split :: Key -> IntMap a -> (IntMap a, IntMap a)
- UU.DData.IntMap: splitLookup :: Key -> IntMap a -> (Maybe a, IntMap a, IntMap a)
- UU.DData.IntMap: subset :: (Eq a) => IntMap a -> IntMap a -> Bool
- UU.DData.IntMap: subsetBy :: (a -> a -> Bool) -> IntMap a -> IntMap a -> Bool
- UU.DData.IntMap: toAscList :: IntMap a -> [(Key, a)]
- UU.DData.IntMap: toList :: IntMap a -> [(Key, a)]
- UU.DData.IntMap: type Key = Int
- UU.DData.IntMap: union :: IntMap a -> IntMap a -> IntMap a
- UU.DData.IntMap: unionWith :: (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
- UU.DData.IntMap: unionWithKey :: (Key -> a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
- UU.DData.IntMap: unions :: [IntMap a] -> IntMap a
- UU.DData.IntMap: update :: (a -> Maybe a) -> Key -> IntMap a -> IntMap a
- UU.DData.IntMap: updateLookupWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> (Maybe a, IntMap a)
- UU.DData.IntMap: updateWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> IntMap a
- UU.DData.IntSet: (\\) :: IntSet -> IntSet -> IntSet
- UU.DData.IntSet: data IntSet
- UU.DData.IntSet: delete :: Int -> IntSet -> IntSet
- UU.DData.IntSet: difference :: IntSet -> IntSet -> IntSet
- UU.DData.IntSet: elems :: IntSet -> [Int]
- UU.DData.IntSet: empty :: IntSet
- UU.DData.IntSet: filter :: (Int -> Bool) -> IntSet -> IntSet
- UU.DData.IntSet: fold :: (Int -> b -> b) -> b -> IntSet -> b
- UU.DData.IntSet: fromAscList :: [Int] -> IntSet
- UU.DData.IntSet: fromDistinctAscList :: [Int] -> IntSet
- UU.DData.IntSet: fromList :: [Int] -> IntSet
- UU.DData.IntSet: insert :: Int -> IntSet -> IntSet
- UU.DData.IntSet: instance Eq IntSet
- UU.DData.IntSet: instance Show IntSet
- UU.DData.IntSet: intersection :: IntSet -> IntSet -> IntSet
- UU.DData.IntSet: isEmpty :: IntSet -> Bool
- UU.DData.IntSet: member :: Int -> IntSet -> Bool
- UU.DData.IntSet: partition :: (Int -> Bool) -> IntSet -> (IntSet, IntSet)
- UU.DData.IntSet: properSubset :: IntSet -> IntSet -> Bool
- UU.DData.IntSet: showTree :: IntSet -> String
- UU.DData.IntSet: showTreeWith :: Bool -> Bool -> IntSet -> String
- UU.DData.IntSet: single :: Int -> IntSet
- UU.DData.IntSet: size :: IntSet -> Int
- UU.DData.IntSet: split :: Int -> IntSet -> (IntSet, IntSet)
- UU.DData.IntSet: splitMember :: Int -> IntSet -> (Bool, IntSet, IntSet)
- UU.DData.IntSet: subset :: IntSet -> IntSet -> Bool
- UU.DData.IntSet: toAscList :: IntSet -> [Int]
- UU.DData.IntSet: toList :: IntSet -> [Int]
- UU.DData.IntSet: union :: IntSet -> IntSet -> IntSet
- UU.DData.IntSet: unions :: [IntSet] -> IntSet
- UU.DData.Map: (!) :: (Ord k) => Map k a -> k -> a
- UU.DData.Map: (\\) :: (Ord k) => Map k a -> Map k a -> Map k a
- UU.DData.Map: adjust :: (Ord k) => (a -> a) -> k -> Map k a -> Map k a
- UU.DData.Map: adjustWithKey :: (Ord k) => (k -> a -> a) -> k -> Map k a -> Map k a
- UU.DData.Map: assocs :: Map k a -> [(k, a)]
- UU.DData.Map: data Map k a
- UU.DData.Map: delete :: (Ord k) => k -> Map k a -> Map k a
- UU.DData.Map: deleteAt :: Int -> Map k a -> Map k a
- UU.DData.Map: deleteFindMax :: Map k a -> ((k, a), Map k a)
- UU.DData.Map: deleteFindMin :: Map k a -> ((k, a), Map k a)
- UU.DData.Map: deleteMax :: Map k a -> Map k a
- UU.DData.Map: deleteMin :: Map k a -> Map k a
- UU.DData.Map: difference :: (Ord k) => Map k a -> Map k a -> Map k a
- UU.DData.Map: differenceWith :: (Ord k) => (a -> a -> Maybe a) -> Map k a -> Map k a -> Map k a
- UU.DData.Map: differenceWithKey :: (Ord k) => (k -> a -> a -> Maybe a) -> Map k a -> Map k a -> Map k a
- UU.DData.Map: elemAt :: Int -> Map k a -> (k, a)
- UU.DData.Map: elems :: Map k a -> [a]
- UU.DData.Map: empty :: Map k a
- UU.DData.Map: filter :: (Ord k) => (a -> Bool) -> Map k a -> Map k a
- UU.DData.Map: filterWithKey :: (Ord k) => (k -> a -> Bool) -> Map k a -> Map k a
- UU.DData.Map: find :: (Ord k) => k -> Map k a -> a
- UU.DData.Map: findIndex :: (Ord k) => k -> Map k a -> Int
- UU.DData.Map: findMax :: Map k a -> (k, a)
- UU.DData.Map: findMin :: Map k a -> (k, a)
- UU.DData.Map: findWithDefault :: (Ord k) => a -> k -> Map k a -> a
- UU.DData.Map: fold :: (a -> b -> b) -> b -> Map k a -> b
- UU.DData.Map: foldWithKey :: (k -> a -> b -> b) -> b -> Map k a -> b
- UU.DData.Map: fromAscList :: (Eq k) => [(k, a)] -> Map k a
- UU.DData.Map: fromAscListWith :: (Eq k) => (a -> a -> a) -> [(k, a)] -> Map k a
- UU.DData.Map: fromAscListWithKey :: (Eq k) => (k -> a -> a -> a) -> [(k, a)] -> Map k a
- UU.DData.Map: fromDistinctAscList :: [(k, a)] -> Map k a
- UU.DData.Map: fromList :: (Ord k) => [(k, a)] -> Map k a
- UU.DData.Map: fromListWith :: (Ord k) => (a -> a -> a) -> [(k, a)] -> Map k a
- UU.DData.Map: fromListWithKey :: (Ord k) => (k -> a -> a -> a) -> [(k, a)] -> Map k a
- UU.DData.Map: insert :: (Ord k) => k -> a -> Map k a -> Map k a
- UU.DData.Map: insertLookupWithKey :: (Ord k) => (k -> a -> a -> a) -> k -> a -> Map k a -> (Maybe a, Map k a)
- UU.DData.Map: insertWith :: (Ord k) => (a -> a -> a) -> k -> a -> Map k a -> Map k a
- UU.DData.Map: insertWithKey :: (Ord k) => (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a
- UU.DData.Map: instance (Eq k, Eq a) => Eq (Map k a)
- UU.DData.Map: instance (Show k, Show a) => Show (Map k a)
- UU.DData.Map: instance Functor (Map k)
- UU.DData.Map: intersection :: (Ord k) => Map k a -> Map k a -> Map k a
- UU.DData.Map: intersectionWith :: (Ord k) => (a -> a -> a) -> Map k a -> Map k a -> Map k a
- UU.DData.Map: intersectionWithKey :: (Ord k) => (k -> a -> a -> a) -> Map k a -> Map k a -> Map k a
- UU.DData.Map: isEmpty :: Map k a -> Bool
- UU.DData.Map: keys :: Map k a -> [k]
- UU.DData.Map: lookup :: (Ord k) => k -> Map k a -> Maybe a
- UU.DData.Map: lookupIndex :: (Ord k) => k -> Map k a -> Maybe Int
- UU.DData.Map: map :: (a -> b) -> Map k a -> Map k b
- UU.DData.Map: mapAccum :: (a -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)
- UU.DData.Map: mapAccumWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)
- UU.DData.Map: mapWithKey :: (k -> a -> b) -> Map k a -> Map k b
- UU.DData.Map: member :: (Ord k) => k -> Map k a -> Bool
- UU.DData.Map: partition :: (Ord k) => (a -> Bool) -> Map k a -> (Map k a, Map k a)
- UU.DData.Map: partitionWithKey :: (Ord k) => (k -> a -> Bool) -> Map k a -> (Map k a, Map k a)
- UU.DData.Map: properSubset :: (Ord k, Eq a) => Map k a -> Map k a -> Bool
- UU.DData.Map: properSubsetBy :: (Ord k, Eq a) => (a -> a -> Bool) -> Map k a -> Map k a -> Bool
- UU.DData.Map: showTree :: (Show k, Show a) => Map k a -> String
- UU.DData.Map: showTreeWith :: (k -> a -> String) -> Bool -> Bool -> Map k a -> String
- UU.DData.Map: single :: k -> a -> Map k a
- UU.DData.Map: size :: Map k a -> Int
- UU.DData.Map: split :: (Ord k) => k -> Map k a -> (Map k a, Map k a)
- UU.DData.Map: splitLookup :: (Ord k) => k -> Map k a -> (Maybe a, Map k a, Map k a)
- UU.DData.Map: subset :: (Ord k, Eq a) => Map k a -> Map k a -> Bool
- UU.DData.Map: subsetBy :: (Ord k) => (a -> a -> Bool) -> Map k a -> Map k a -> Bool
- UU.DData.Map: toAscList :: Map k a -> [(k, a)]
- UU.DData.Map: toList :: Map k a -> [(k, a)]
- UU.DData.Map: union :: (Ord k) => Map k a -> Map k a -> Map k a
- UU.DData.Map: unionWith :: (Ord k) => (a -> a -> a) -> Map k a -> Map k a -> Map k a
- UU.DData.Map: unionWithKey :: (Ord k) => (k -> a -> a -> a) -> Map k a -> Map k a -> Map k a
- UU.DData.Map: unions :: (Ord k) => [Map k a] -> Map k a
- UU.DData.Map: update :: (Ord k) => (a -> Maybe a) -> k -> Map k a -> Map k a
- UU.DData.Map: updateAt :: (k -> a -> Maybe a) -> Int -> Map k a -> Map k a
- UU.DData.Map: updateLookupWithKey :: (Ord k) => (k -> a -> Maybe a) -> k -> Map k a -> (Maybe a, Map k a)
- UU.DData.Map: updateMax :: (a -> Maybe a) -> Map k a -> Map k a
- UU.DData.Map: updateMaxWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a
- UU.DData.Map: updateMin :: (a -> Maybe a) -> Map k a -> Map k a
- UU.DData.Map: updateMinWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a
- UU.DData.Map: updateWithKey :: (Ord k) => (k -> a -> Maybe a) -> k -> Map k a -> Map k a
- UU.DData.Map: valid :: (Ord k) => Map k a -> Bool
- UU.DData.MultiSet: (\\) :: (Ord a) => MultiSet a -> MultiSet a -> MultiSet a
- UU.DData.MultiSet: data MultiSet a
- UU.DData.MultiSet: delete :: (Ord a) => a -> MultiSet a -> MultiSet a
- UU.DData.MultiSet: deleteAll :: (Ord a) => a -> MultiSet a -> MultiSet a
- UU.DData.MultiSet: deleteMax :: MultiSet a -> MultiSet a
- UU.DData.MultiSet: deleteMaxAll :: MultiSet a -> MultiSet a
- UU.DData.MultiSet: deleteMin :: MultiSet a -> MultiSet a
- UU.DData.MultiSet: deleteMinAll :: MultiSet a -> MultiSet a
- UU.DData.MultiSet: difference :: (Ord a) => MultiSet a -> MultiSet a -> MultiSet a
- UU.DData.MultiSet: distinctSize :: MultiSet a -> Int
- UU.DData.MultiSet: elems :: MultiSet a -> [a]
- UU.DData.MultiSet: empty :: MultiSet a
- UU.DData.MultiSet: filter :: (Ord a) => (a -> Bool) -> MultiSet a -> MultiSet a
- UU.DData.MultiSet: findMax :: MultiSet a -> a
- UU.DData.MultiSet: findMin :: MultiSet a -> a
- UU.DData.MultiSet: fold :: (a -> b -> b) -> b -> MultiSet a -> b
- UU.DData.MultiSet: foldOccur :: (a -> Int -> b -> b) -> b -> MultiSet a -> b
- UU.DData.MultiSet: fromAscList :: (Eq a) => [a] -> MultiSet a
- UU.DData.MultiSet: fromAscOccurList :: (Ord a) => [(a, Int)] -> MultiSet a
- UU.DData.MultiSet: fromDistinctAscList :: [a] -> MultiSet a
- UU.DData.MultiSet: fromList :: (Ord a) => [a] -> MultiSet a
- UU.DData.MultiSet: fromMap :: (Ord a) => Map a Int -> MultiSet a
- UU.DData.MultiSet: fromOccurList :: (Ord a) => [(a, Int)] -> MultiSet a
- UU.DData.MultiSet: fromOccurMap :: Map a Int -> MultiSet a
- UU.DData.MultiSet: insert :: (Ord a) => a -> MultiSet a -> MultiSet a
- UU.DData.MultiSet: insertMany :: (Ord a) => a -> Int -> MultiSet a -> MultiSet a
- UU.DData.MultiSet: instance (Eq a) => Eq (MultiSet a)
- UU.DData.MultiSet: instance (Show a) => Show (MultiSet a)
- UU.DData.MultiSet: intersection :: (Ord a) => MultiSet a -> MultiSet a -> MultiSet a
- UU.DData.MultiSet: isEmpty :: MultiSet a -> Bool
- UU.DData.MultiSet: member :: (Ord a) => a -> MultiSet a -> Bool
- UU.DData.MultiSet: occur :: (Ord a) => a -> MultiSet a -> Int
- UU.DData.MultiSet: partition :: (Ord a) => (a -> Bool) -> MultiSet a -> (MultiSet a, MultiSet a)
- UU.DData.MultiSet: properSubset :: (Ord a) => MultiSet a -> MultiSet a -> Bool
- UU.DData.MultiSet: showTree :: (Show a) => MultiSet a -> String
- UU.DData.MultiSet: showTreeWith :: (Show a) => Bool -> Bool -> MultiSet a -> String
- UU.DData.MultiSet: single :: a -> MultiSet a
- UU.DData.MultiSet: size :: MultiSet a -> Int
- UU.DData.MultiSet: subset :: (Ord a) => MultiSet a -> MultiSet a -> Bool
- UU.DData.MultiSet: toAscList :: MultiSet a -> [a]
- UU.DData.MultiSet: toAscOccurList :: MultiSet a -> [(a, Int)]
- UU.DData.MultiSet: toList :: MultiSet a -> [a]
- UU.DData.MultiSet: toMap :: MultiSet a -> Map a Int
- UU.DData.MultiSet: toOccurList :: MultiSet a -> [(a, Int)]
- UU.DData.MultiSet: union :: (Ord a) => MultiSet a -> MultiSet a -> MultiSet a
- UU.DData.MultiSet: unions :: (Ord a) => [MultiSet a] -> MultiSet a
- UU.DData.MultiSet: valid :: (Ord a) => MultiSet a -> Bool
- UU.DData.Queue: (<>) :: Queue a -> Queue a -> Queue a
- UU.DData.Queue: append :: Queue a -> Queue a -> Queue a
- UU.DData.Queue: data Queue a
- UU.DData.Queue: elems :: Queue a -> [a]
- UU.DData.Queue: empty :: Queue a
- UU.DData.Queue: filter :: (a -> Bool) -> Queue a -> Queue a
- UU.DData.Queue: foldL :: (b -> a -> b) -> b -> Queue a -> b
- UU.DData.Queue: foldR :: (a -> b -> b) -> b -> Queue a -> b
- UU.DData.Queue: fromList :: [a] -> Queue a
- UU.DData.Queue: front :: Queue a -> Maybe (a, Queue a)
- UU.DData.Queue: head :: Queue a -> a
- UU.DData.Queue: insert :: a -> Queue a -> Queue a
- UU.DData.Queue: instance (Eq a) => Eq (Queue a)
- UU.DData.Queue: instance (Show a) => Show (Queue a)
- UU.DData.Queue: isEmpty :: Queue a -> Bool
- UU.DData.Queue: length :: Queue a -> Int
- UU.DData.Queue: partition :: (a -> Bool) -> Queue a -> (Queue a, Queue a)
- UU.DData.Queue: single :: a -> Queue a
- UU.DData.Queue: tail :: Queue a -> Queue a
- UU.DData.Queue: toList :: Queue a -> [a]
- UU.DData.Scc: instance (Show v) => Show (Graph v)
- UU.DData.Scc: instance (Show v) => Show (Tree v)
- UU.DData.Scc: scc :: (Ord v) => [(v, [v])] -> [[v]]
- UU.DData.Seq: (<>) :: Seq a -> Seq a -> Seq a
- UU.DData.Seq: append :: Seq a -> Seq a -> Seq a
- UU.DData.Seq: cons :: a -> Seq a -> Seq a
- UU.DData.Seq: data Seq a
- UU.DData.Seq: empty :: Seq a
- UU.DData.Seq: fromList :: [a] -> Seq a
- UU.DData.Seq: single :: a -> Seq a
- UU.DData.Seq: toList :: Seq a -> [a]
- UU.DData.Set: (\\) :: (Ord a) => Set a -> Set a -> Set a
- UU.DData.Set: data Set a
- UU.DData.Set: delete :: (Ord a) => a -> Set a -> Set a
- UU.DData.Set: deleteFindMax :: Set a -> (a, Set a)
- UU.DData.Set: deleteFindMin :: Set a -> (a, Set a)
- UU.DData.Set: deleteMax :: Set a -> Set a
- UU.DData.Set: deleteMin :: Set a -> Set a
- UU.DData.Set: difference :: (Ord a) => Set a -> Set a -> Set a
- UU.DData.Set: elems :: Set a -> [a]
- UU.DData.Set: empty :: Set a
- UU.DData.Set: filter :: (Ord a) => (a -> Bool) -> Set a -> Set a
- UU.DData.Set: findMax :: Set a -> a
- UU.DData.Set: findMin :: Set a -> a
- UU.DData.Set: fold :: (a -> b -> b) -> b -> Set a -> b
- UU.DData.Set: fromAscList :: (Eq a) => [a] -> Set a
- UU.DData.Set: fromDistinctAscList :: [a] -> Set a
- UU.DData.Set: fromList :: (Ord a) => [a] -> Set a
- UU.DData.Set: insert :: (Ord a) => a -> Set a -> Set a
- UU.DData.Set: instance (Eq a) => Eq (Set a)
- UU.DData.Set: instance (Show a) => Show (Set a)
- UU.DData.Set: intersection :: (Ord a) => Set a -> Set a -> Set a
- UU.DData.Set: isEmpty :: Set a -> Bool
- UU.DData.Set: member :: (Ord a) => a -> Set a -> Bool
- UU.DData.Set: partition :: (Ord a) => (a -> Bool) -> Set a -> (Set a, Set a)
- UU.DData.Set: properSubset :: (Ord a) => Set a -> Set a -> Bool
- UU.DData.Set: showTree :: (Show a) => Set a -> String
- UU.DData.Set: showTreeWith :: (Show a) => Bool -> Bool -> Set a -> String
- UU.DData.Set: single :: a -> Set a
- UU.DData.Set: size :: Set a -> Int
- UU.DData.Set: split :: (Ord a) => a -> Set a -> (Set a, Set a)
- UU.DData.Set: splitMember :: (Ord a) => a -> Set a -> (Bool, Set a, Set a)
- UU.DData.Set: subset :: (Ord a) => Set a -> Set a -> Bool
- UU.DData.Set: toAscList :: Set a -> [a]
- UU.DData.Set: toList :: Set a -> [a]
- UU.DData.Set: union :: (Ord a) => Set a -> Set a -> Set a
- UU.DData.Set: unions :: (Ord a) => [Set a] -> Set a
- UU.DData.Set: valid :: (Ord a) => Set a -> Bool
+ UU.Parsing.Offside: Trigger_IndentGE :: OffsideTrigger
+ UU.Parsing.Offside: Trigger_IndentGT :: OffsideTrigger
+ UU.Parsing.Offside: data OffsideTrigger
+ UU.Parsing.Offside: instance Eq OffsideTrigger
+ UU.Parsing.Offside: scanOffsideWithTriggers :: (InputState i s p, Position p, Eq s) => s -> s -> s -> [(OffsideTrigger, s)] -> i -> OffsideInput i s p

Files

− src/UU/DData/IntBag.hs
@@ -1,368 +0,0 @@----------------------------------------------------------------------------------{-| Module      :  IntBag-    Copyright   :  (c) Daan Leijen 2002-    License     :  BSD-style--    Maintainer  :  daan@cs.uu.nl-    Stability   :  provisional-    Portability :  portable--  An efficient implementation of bags of integers on top of the "IntMap" module. --  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). For more information, see-  the references in the "IntMap" module.--}----------------------------------------------------------------------------------}-module UU.DData.IntBag ( -            -- * Bag type-              IntBag          -- instance Eq,Show-            -            -- * Operators-            , (\\)--            -- *Query-            , isEmpty-            , size-            , distinctSize-            , member-            , occur--            , subset-            , properSubset-            -            -- * Construction-            , empty-            , single-            , insert-            , insertMany-            , delete-            , deleteAll-            -            -- * Combine-            , union-            , difference-            , intersection-            , unions-            -            -- * Filter-            , filter-            , partition--            -- * Fold-            , fold-            , foldOccur-           -            -- * Conversion-            , elems--            -- ** List-            , toList-            , fromList--            -- ** Ordered list-            , toAscList-            , fromAscList-            , fromDistinctAscList--            -- ** Occurrence lists-            , toOccurList-            , toAscOccurList-            , fromOccurList-            , fromAscOccurList--            -- ** IntMap-            , toMap-            , fromMap-            , fromOccurMap-            -            -- * Debugging-            , showTree-            , showTreeWith-            ) where--import Prelude   hiding  (map,filter)-import qualified Prelude (map,filter)--import qualified UU.DData.IntMap as M--{---------------------------------------------------------------------  Operators---------------------------------------------------------------------}-infixl 9 \\ ------ | /O(n+m)/. See 'difference'.-(\\) ::  IntBag -> IntBag -> IntBag-b1 \\ b2 = difference b1 b2--{---------------------------------------------------------------------  IntBags are a simple wrapper around Maps, 'Map.Map'---------------------------------------------------------------------}--- | A bag of integers.-newtype IntBag  = IntBag (M.IntMap Int)--{---------------------------------------------------------------------  Query---------------------------------------------------------------------}--- | /O(1)/. Is the bag empty?-isEmpty :: IntBag -> Bool-isEmpty (IntBag m)  -  = M.isEmpty m---- | /O(n)/. Returns the number of distinct elements in the bag, ie. (@distinctSize bag == length (nub (toList bag))@).-distinctSize :: IntBag -> Int-distinctSize (IntBag m)     -  = M.size m---- | /O(n)/. The number of elements in the bag.-size :: IntBag -> Int-size b-  = foldOccur (\x n m -> n+m) 0 b---- | /O(min(n,W))/. Is the element in the bag?-member ::  Int -> IntBag -> Bool-member x m-  = (occur x m > 0)---- | /O(min(n,W))/. The number of occurrences of an element in the bag.-occur ::  Int -> IntBag -> Int-occur x (IntBag m)-  = case M.lookup x m of-      Nothing -> 0-      Just n  -> n---- | /O(n+m)/. Is this a subset of the bag? -subset ::  IntBag -> IntBag -> Bool-subset (IntBag m1) (IntBag m2)-  = M.subsetBy (<=) m1 m2---- | /O(n+m)/. Is this a proper subset? (ie. a subset and not equal)-properSubset ::  IntBag -> IntBag -> Bool-properSubset b1 b2-  = subset b1 b2 && (b1 /= b2)--{---------------------------------------------------------------------  Construction---------------------------------------------------------------------}--- | /O(1)/. Create an empty bag.-empty :: IntBag-empty-  = IntBag (M.empty)---- | /O(1)/. Create a singleton bag.-single :: Int -> IntBag-single x -  = IntBag (M.single x 0)-    -{---------------------------------------------------------------------  Insertion, Deletion---------------------------------------------------------------------}--- | /O(min(n,W))/. Insert an element in the bag.-insert ::  Int -> IntBag -> IntBag-insert x (IntBag m)          -  = IntBag (M.insertWith (+) x 1 m)---- | /O(min(n,W))/. The expression (@insertMany x count bag@)--- inserts @count@ instances of @x@ in the bag @bag@.-insertMany ::  Int -> Int -> IntBag -> IntBag-insertMany x count (IntBag m)          -  = IntBag (M.insertWith (+) x count m)---- | /O(min(n,W))/. Delete a single element.-delete ::  Int -> IntBag -> IntBag-delete x (IntBag m)-  = IntBag (M.updateWithKey f x m)-  where-    f x n  | n > 0     = Just (n-1)-           | otherwise = Nothing---- | /O(min(n,W))/. Delete all occurrences of an element.-deleteAll ::  Int -> IntBag -> IntBag-deleteAll x (IntBag m)-  = IntBag (M.delete x m)--{---------------------------------------------------------------------  Combine---------------------------------------------------------------------}--- | /O(n+m)/. Union of two bags. The union adds the elements together.------ > IntBag\> union (fromList [1,1,2]) (fromList [1,2,2,3])--- > {1,1,1,2,2,2,3}-union ::  IntBag -> IntBag -> IntBag-union (IntBag t1) (IntBag t2)-  = IntBag (M.unionWith (+) t1 t2)---- | /O(n+m)/. Intersection of two bags.------ > IntBag\> intersection (fromList [1,1,2]) (fromList [1,2,2,3])--- > {1,2}-intersection ::  IntBag -> IntBag -> IntBag-intersection (IntBag t1) (IntBag t2)-  = IntBag (M.intersectionWith min t1 t2)---- | /O(n+m)/. Difference between two bags.------ > IntBag\> difference (fromList [1,1,2]) (fromList [1,2,2,3])--- > {1}-difference   ::  IntBag -> IntBag -> IntBag-difference (IntBag t1) (IntBag t2)-  = IntBag (M.differenceWithKey f t1 t2)-  where-    f x n m  | n-m > 0   = Just (n-m)-             | otherwise = Nothing---- | The union of a list of bags.-unions ::  [IntBag] -> IntBag-unions bags-  = IntBag (M.unions [m | IntBag m <- bags])--{---------------------------------------------------------------------  Filter and partition---------------------------------------------------------------------}--- | /O(n)/. Filter all elements that satisfy some predicate.-filter ::  (Int -> Bool) -> IntBag -> IntBag-filter p (IntBag m)-  = IntBag (M.filterWithKey (\x n -> p x) m)---- | /O(n)/. Partition the bag according to some predicate.-partition ::  (Int -> Bool) -> IntBag -> (IntBag,IntBag)-partition p (IntBag m)-  = (IntBag l,IntBag r)-  where-    (l,r) = M.partitionWithKey (\x n -> p x) m--{---------------------------------------------------------------------  Fold---------------------------------------------------------------------}--- | /O(n)/. Fold over each element in the bag.-fold :: (Int -> b -> b) -> b -> IntBag -> b-fold f z (IntBag m)-  = M.foldWithKey apply z m-  where-    apply x n z  | n > 0     = apply x (n-1) (f x z)-                 | otherwise = z---- | /O(n)/. Fold over all occurrences of an element at once. --- In a call (@foldOccur f z bag@), the function @f@ takes--- the element first and than the occur count.-foldOccur :: (Int -> Int -> b -> b) -> b -> IntBag -> b-foldOccur f z (IntBag m)-  = M.foldWithKey f z m--{---------------------------------------------------------------------  List variations ---------------------------------------------------------------------}--- | /O(n)/. The list of elements.-elems :: IntBag -> [Int]-elems s-  = toList s--{---------------------------------------------------------------------  Lists ---------------------------------------------------------------------}--- | /O(n)/. Create a list with all elements.-toList :: IntBag -> [Int]-toList s-  = toAscList s---- | /O(n)/. Create an ascending list of all elements.-toAscList :: IntBag -> [Int]-toAscList (IntBag m)-  = [y | (x,n) <- M.toAscList m, y <- replicate n x]----- | /O(n*min(n,W))/. Create a bag from a list of elements.-fromList ::  [Int] -> IntBag -fromList xs-  = IntBag (M.fromListWith (+) [(x,1) | x <- xs])---- | /O(n*min(n,W))/. Create a bag from an ascending list.-fromAscList :: [Int] -> IntBag -fromAscList xs-  = IntBag (M.fromAscListWith (+) [(x,1) | x <- xs])---- | /O(n*min(n,W))/. Create a bag from an ascending list of distinct elements.-fromDistinctAscList :: [Int] -> IntBag -fromDistinctAscList xs-  = IntBag (M.fromDistinctAscList [(x,1) | x <- xs])---- | /O(n)/. Create a list of element\/occurrence pairs.-toOccurList :: IntBag -> [(Int,Int)]-toOccurList b-  = toAscOccurList b---- | /O(n)/. Create an ascending list of element\/occurrence pairs.-toAscOccurList :: IntBag -> [(Int,Int)]-toAscOccurList (IntBag m)-  = M.toAscList m---- | /O(n*min(n,W))/. Create a bag from a list of element\/occurrence pairs.-fromOccurList ::  [(Int,Int)] -> IntBag-fromOccurList xs-  = IntBag (M.fromListWith (+) (Prelude.filter (\(x,i) -> i > 0) xs))---- | /O(n*min(n,W))/. Create a bag from an ascending list of element\/occurrence pairs.-fromAscOccurList ::  [(Int,Int)] -> IntBag-fromAscOccurList xs-  = IntBag (M.fromAscListWith (+) (Prelude.filter (\(x,i) -> i > 0) xs))--{---------------------------------------------------------------------  Maps---------------------------------------------------------------------}--- | /O(1)/. Convert to an 'IntMap.IntMap' from elements to number of occurrences.-toMap   :: IntBag -> M.IntMap Int-toMap (IntBag m)-  = m---- | /O(n)/. Convert a 'IntMap.IntMap' from elements to occurrences into a bag.-fromMap ::  M.IntMap Int -> IntBag-fromMap m-  = IntBag (M.filter (>0) m)---- | /O(1)/. Convert a 'IntMap.IntMap' from elements to occurrences into a bag.--- Assumes that the 'IntMap.IntMap' contains only elements that occur at least once.-fromOccurMap :: M.IntMap Int -> IntBag-fromOccurMap m-  = IntBag m--{---------------------------------------------------------------------  Eq, Ord---------------------------------------------------------------------}-instance Eq (IntBag) where-  (IntBag m1) == (IntBag m2)  = (m1==m2) -  (IntBag m1) /= (IntBag m2)  = (m1/=m2)--{---------------------------------------------------------------------  Show---------------------------------------------------------------------}-instance Show (IntBag) where-  showsPrec d b  = showSet (toAscList b)--showSet :: Show a => [a] -> ShowS-showSet []     -  = showString "{}" -showSet (x:xs) -  = showChar '{' . shows x . showTail xs-  where-    showTail []     = showChar '}'-    showTail (x:xs) = showChar ',' . shows x . showTail xs-    --{---------------------------------------------------------------------  Debugging---------------------------------------------------------------------}--- | /O(n)/. Show the tree structure that implements the 'IntBag'. The tree--- is shown as a compressed and /hanging/.-showTree :: IntBag -> String-showTree bag-  = showTreeWith True False bag---- | /O(n)/. The expression (@showTreeWith hang wide map@) shows--- the tree that implements the bag. The tree is shown /hanging/ when @hang@ is @True@ --- and otherwise as a /rotated/ tree. When @wide@ is @True@ an extra wide version--- is shown.-showTreeWith :: Bool -> Bool -> IntBag -> String-showTreeWith hang wide (IntBag m)-  = M.showTreeWith hang wide m-
− src/UU/DData/IntMap.hs
@@ -1,1240 +0,0 @@-{-# OPTIONS -cpp -fglasgow-exts #-} --------------------------------------------------------------------------------- -{-| Module      :  IntMap-    Copyright   :  (c) Daan Leijen 2002-    License     :  BSD-style--    Maintainer  :  daan@cs.uu.nl-    Stability   :  provisional-    Portability :  portable--  An efficient implementation of maps from integer keys to values. -  -  1) The module exports some names that clash with the "Prelude" -- 'lookup', 'map', and 'filter'. -      If you want to use "IntMap" unqualified, these functions should be hidden.--      > import Prelude hiding (map,lookup,filter)-      > import IntMap--      Another solution is to use qualified names. --      > import qualified IntMap-      >-      > ... IntMap.single "Paris" "France"--      Or, if you prefer a terse coding style:--      > import qualified IntMap as M-      >-      > ... M.single "Paris" "France"--  2) 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 "Map" and "Data.FiniteMap").-   -  *  Chris Okasaki and Andy Gill,  \"/Fast Mergeable Integer Maps/\",-     Workshop on ML, September 1998, pages 77--86, <http://www.cse.ogi.edu/~andy/pub/finite.htm>--  *  D.R. Morrison, \"/PATRICIA -- Practical Algorithm To Retrieve Information-     Coded In Alphanumeric/\", Journal of the ACM, 15(4), October 1968, pages 514--534.--  3) 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). --}---------------------------------------------------------------------------------- -module UU.DData.IntMap  ( -            -- * Map type-              IntMap, Key          -- instance Eq,Show--            -- * Operators-            , (!), (\\)--            -- * Query-            , isEmpty-            , size-            , member-            , lookup-            , find          -            , findWithDefault-            -            -- * Construction-            , empty-            , single--            -- ** Insertion-            , insert-            , insertWith, insertWithKey, insertLookupWithKey-            -            -- ** Delete\/Update-            , delete-            , adjust-            , adjustWithKey-            , update-            , updateWithKey-            , updateLookupWithKey-  -            -- * Combine--            -- ** Union-            , union         -            , unionWith          -            , unionWithKey-            , unions--            -- ** Difference-            , difference-            , differenceWith-            , differenceWithKey-            -            -- ** Intersection-            , intersection           -            , intersectionWith-            , intersectionWithKey--            -- * Traversal-            -- ** Map-            , map-            , mapWithKey-            , mapAccum-            , mapAccumWithKey-            -            -- ** Fold-            , fold-            , foldWithKey--            -- * Conversion-            , elems-            , keys-            , assocs-            -            -- ** Lists-            , toList-            , fromList-            , fromListWith-            , fromListWithKey--            -- ** Ordered lists-            , toAscList-            , fromAscList-            , fromAscListWith-            , fromAscListWithKey-            , fromDistinctAscList--            -- * Filter -            , filter-            , filterWithKey-            , partition-            , partitionWithKey--            , split         -            , splitLookup   --            -- * Subset-            , subset, subsetBy-            , properSubset, properSubsetBy-            -            -- * Debugging-            , showTree-            , showTreeWith-            ) where---import Prelude hiding (lookup,map,filter)-import Bits -import Int--{---- just for testing-import qualified Prelude-import Debug.QuickCheck -import List (nub,sort)-import qualified List--}  --#ifdef __GLASGOW_HASKELL__-{---------------------------------------------------------------------  GHC: use unboxing to get @shiftRL@ inlined.---------------------------------------------------------------------}-#if __GLASGOW_HASKELL__ >= 503-import GHC.Word-import GHC.Exts ( Word(..), Int(..), shiftRL# )-#else-import Word-import GlaExts ( Word(..), Int(..), shiftRL# )-#endif--type Nat = Word--natFromInt :: Key -> Nat-natFromInt i = fromIntegral i--intFromNat :: Nat -> Key-intFromNat w = fromIntegral w--shiftRL :: Nat -> Key -> Nat-shiftRL (W# x) (I# i)-  = W# (shiftRL# x i)--#elif __HUGS__-{--------------------------------------------------------------------- Hugs: - * raises errors on boundary values when using 'fromIntegral'-   but not with the deprecated 'fromInt/toInt'. - * Older Hugs doesn't define 'Word'.- * Newer Hugs defines 'Word' in the Prelude but no operations.---------------------------------------------------------------------}-import Word--type Nat = Word32   -- illegal on 64-bit platforms!--natFromInt :: Key -> Nat-natFromInt i = fromInt i--intFromNat :: Nat -> Key-intFromNat w = toInt w--shiftRL :: Nat -> Key -> Nat-shiftRL x i   = shiftR x i--#else-{---------------------------------------------------------------------  'Standard' Haskell-  * A "Nat" is a natural machine word (an unsigned Int)---------------------------------------------------------------------}-import Word--type Nat = Word--natFromInt :: Key -> Nat-natFromInt i = fromIntegral i--intFromNat :: Nat -> Key-intFromNat w = fromIntegral w--shiftRL :: Nat -> Key -> Nat-shiftRL w i   = shiftR w i--#endif--infixl 9 \\ ----{---------------------------------------------------------------------  Operators---------------------------------------------------------------------}---- | /O(min(n,W))/. See 'find'.-(!) :: IntMap a -> Key -> a-(!) m k    = find k m---- | /O(n+m)/. See 'difference'.-(\\) :: IntMap a -> IntMap a -> IntMap a-m1 \\ m2 = difference m1 m2--{---------------------------------------------------------------------  Types  ---------------------------------------------------------------------}--- | A map of integers to values @a@.-data IntMap a = Nil-              | Tip !Key a-              | Bin !Prefix !Mask !(IntMap a) !(IntMap a) --type Prefix = Int-type Mask   = Int-type Key    = Int--{---------------------------------------------------------------------  Query---------------------------------------------------------------------}--- | /O(1)/. Is the map empty?-isEmpty :: IntMap a -> Bool-isEmpty Nil   = True-isEmpty other = False---- | /O(n)/. Number of elements in the map.-size :: IntMap a -> Int-size t-  = case t of-      Bin p m l r -> size l + size r-      Tip k x -> 1-      Nil     -> 0---- | /O(min(n,W))/. Is the key a member of the map?-member :: Key -> IntMap a -> Bool-member k m-  = case lookup k m of-      Nothing -> False-      Just x  -> True-    --- | /O(min(n,W))/. Lookup the value of a key in the map.-lookup :: Key -> IntMap a -> Maybe a-lookup k t-  = case t of-      Bin p m l r -        | nomatch k p m -> Nothing-        | zero k m      -> lookup k l-        | otherwise     -> lookup k r-      Tip kx x -        | (k==kx)   -> Just x-        | otherwise -> Nothing-      Nil -> Nothing---- | /O(min(n,W))/. Find the value of a key. Calls @error@ when the element can not be found.-find :: Key -> IntMap a -> a-find k m-  = case lookup k m of-      Nothing -> error ("IntMap.find: key " ++ show k ++ " is not an element of the map")-      Just x  -> x---- | /O(min(n,W))/. The expression @(findWithDefault def k map)@ returns the value of key @k@ or returns @def@ when--- the key is not an element of the map.-findWithDefault :: a -> Key -> IntMap a -> a-findWithDefault def k m-  = case lookup k m of-      Nothing -> def-      Just x  -> x--{---------------------------------------------------------------------  Construction---------------------------------------------------------------------}--- | /O(1)/. The empty map.-empty :: IntMap a-empty-  = Nil---- | /O(1)/. A map of one element.-single :: Key -> a -> IntMap a-single k x-  = Tip k x--{---------------------------------------------------------------------  Insert-  'insert' is the inlined version of 'insertWith (\k x y -> x)'---------------------------------------------------------------------}--- | /O(min(n,W))/. Insert a new key\/value pair in the map. When the key --- is already an element of the set, it's value is replaced by the new value, --- ie. 'insert' is left-biased.-insert :: Key -> a -> IntMap a -> IntMap a-insert k x t-  = case t of-      Bin p m l r -        | nomatch k p m -> join 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 y -        | k==ky         -> Tip k x-        | otherwise     -> join 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 :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a-insertWith f k x t-  = insertWithKey (\k x y -> f x y) k x t---- | /O(min(n,W))/. Insert with a combining function.-insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> IntMap a-insertWithKey f k x t-  = case t of-      Bin p m l r -        | nomatch k p m -> join 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)-      Tip ky y -        | k==ky         -> Tip k (f k x y)-        | otherwise     -> join k (Tip k x) ky t-      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@).-insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> (Maybe a, IntMap a)-insertLookupWithKey f k x t-  = case t of-      Bin p m l r -        | nomatch k p m -> (Nothing,join 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')-      Tip ky y -        | k==ky         -> (Just y,Tip k (f k x y))-        | otherwise     -> (Nothing,join k (Tip k x) ky t)-      Nil -> (Nothing,Tip k x)---{---------------------------------------------------------------------  Deletion-  [delete] is the inlined version of [deleteWith (\k x -> Nothing)]---------------------------------------------------------------------}--- | /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 :: Key -> IntMap a -> IntMap a-delete k t-  = case t of-      Bin p m l r -        | nomatch k p m -> t-        | zero k m      -> bin p m (delete k l) r-        | otherwise     -> bin p m l (delete k r)-      Tip ky y -        | k==ky         -> Nil-        | otherwise     -> t-      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 ::  (a -> a) -> Key -> IntMap a -> IntMap a-adjust f k m-  = adjustWithKey (\k 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.-adjustWithKey ::  (Key -> a -> a) -> Key -> IntMap a -> IntMap a-adjustWithKey f k m-  = updateWithKey (\k x -> Just (f k x)) k m---- | /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@.-update ::  (a -> Maybe a) -> Key -> IntMap a -> IntMap a-update f k m-  = updateWithKey (\k x -> f x) k m---- | /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@.-updateWithKey ::  (Key -> a -> Maybe a) -> Key -> IntMap a -> IntMap a-updateWithKey f k t-  = case t of-      Bin p m l r -        | nomatch k p m -> t-        | zero k m      -> bin p m (updateWithKey f k l) r-        | otherwise     -> bin 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.-updateLookupWithKey ::  (Key -> a -> Maybe a) -> Key -> IntMap a -> (Maybe a,IntMap a)-updateLookupWithKey f k t-  = case t of-      Bin p m l r -        | nomatch k p m -> (Nothing,t)-        | zero k m      -> let (found,l') = updateLookupWithKey f k l in (found,bin p m l' r)-        | otherwise     -> let (found,r') = updateLookupWithKey f k r in (found,bin 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)---{---------------------------------------------------------------------  Union---------------------------------------------------------------------}--- | The union of a list of maps.-unions :: [IntMap a] -> IntMap a-unions xs-  = foldlStrict union empty xs----- | /O(n+m)/. The (left-biased) union of two sets. -union :: IntMap a -> IntMap a -> IntMap a-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      = join p1 t1 p2 t2-  where-    union1  | nomatch p2 p1 m1  = join 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  = join p1 t1 p2 t2-            | zero p1 m2        = Bin p2 m2 (union t1 l2) r2-            | otherwise         = Bin p2 m2 l2 (union t1 r2)--union (Tip k x) t = insert k x t-union t (Tip k x) = insertWith (\x y -> y) k x t  -- right bias-union Nil t       = t-union t Nil       = t---- | /O(n+m)/. The union with a combining function. -unionWith :: (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a-unionWith f m1 m2-  = unionWithKey (\k x y -> f x y) m1 m2---- | /O(n+m)/. The union with a combining function. -unionWithKey :: (Key -> a -> a -> a) -> IntMap a -> IntMap a -> IntMap a-unionWithKey f 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 (unionWithKey f l1 l2) (unionWithKey f r1 r2)-  | otherwise      = join p1 t1 p2 t2-  where-    union1  | nomatch p2 p1 m1  = join p1 t1 p2 t2-            | zero p2 m1        = Bin p1 m1 (unionWithKey f l1 t2) r1-            | otherwise         = Bin p1 m1 l1 (unionWithKey f r1 t2)--    union2  | nomatch p1 p2 m2  = join p1 t1 p2 t2-            | zero p1 m2        = Bin p2 m2 (unionWithKey f t1 l2) r2-            | otherwise         = Bin p2 m2 l2 (unionWithKey f t1 r2)--unionWithKey f (Tip k x) t = insertWithKey f k x t-unionWithKey f t (Tip k x) = insertWithKey (\k x y -> f k y x) k x t  -- right bias-unionWithKey f Nil t  = t-unionWithKey f t Nil  = t--{---------------------------------------------------------------------  Difference---------------------------------------------------------------------}--- | /O(n+m)/. Difference between two maps (based on keys). -difference :: IntMap a -> IntMap a -> IntMap a-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 t1@(Tip k x) t2 -  | member k t2  = Nil-  | otherwise    = t1--difference Nil t       = Nil-difference t (Tip k x) = delete k t-difference t Nil       = t---- | /O(n+m)/. Difference with a combining function. -differenceWith :: (a -> a -> Maybe a) -> IntMap a -> IntMap a -> IntMap a-differenceWith f m1 m2-  = differenceWithKey (\k 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@. -differenceWithKey :: (Key -> a -> a -> Maybe a) -> IntMap a -> IntMap a -> IntMap a-differenceWithKey f 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 (differenceWithKey f l1 l2) (differenceWithKey f r1 r2)-  | otherwise      = t1-  where-    difference1 | nomatch p2 p1 m1  = t1-                | zero p2 m1        = bin p1 m1 (differenceWithKey f l1 t2) r1-                | otherwise         = bin p1 m1 l1 (differenceWithKey f r1 t2)--    difference2 | nomatch p1 p2 m2  = t1-                | zero p1 m2        = differenceWithKey f t1 l2-                | otherwise         = differenceWithKey f t1 r2--differenceWithKey f t1@(Tip k x) t2 -  = case lookup k t2 of-      Just y  -> case f k x y of-                   Just y' -> Tip k y'-                   Nothing -> Nil-      Nothing -> t1--differenceWithKey f Nil t       = Nil-differenceWithKey f t (Tip k y) = updateWithKey (\k x -> f k x y) k t-differenceWithKey f t Nil       = t---{---------------------------------------------------------------------  Intersection---------------------------------------------------------------------}--- | /O(n+m)/. The (left-biased) intersection of two maps (based on keys). -intersection :: IntMap a -> IntMap a -> IntMap a-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@(Tip k x) t2 -  | member k t2  = t1-  | otherwise    = Nil-intersection t (Tip k x) -  = case lookup k t of-      Just y  -> Tip k y-      Nothing -> Nil-intersection Nil t = Nil-intersection t Nil = Nil---- | /O(n+m)/. The intersection with a combining function. -intersectionWith :: (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a-intersectionWith f m1 m2-  = intersectionWithKey (\k x y -> f x y) m1 m2---- | /O(n+m)/. The intersection with a combining function. -intersectionWithKey :: (Key -> a -> a -> a) -> IntMap a -> IntMap a -> IntMap a-intersectionWithKey f 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 (intersectionWithKey f l1 l2) (intersectionWithKey f r1 r2)-  | otherwise      = Nil-  where-    intersection1 | nomatch p2 p1 m1  = Nil-                  | zero p2 m1        = intersectionWithKey f l1 t2-                  | otherwise         = intersectionWithKey f r1 t2--    intersection2 | nomatch p1 p2 m2  = Nil-                  | zero p1 m2        = intersectionWithKey f t1 l2-                  | otherwise         = intersectionWithKey f t1 r2--intersectionWithKey f t1@(Tip k x) t2 -  = case lookup k t2 of-      Just y  -> Tip k (f k x y)-      Nothing -> Nil-intersectionWithKey f t1 (Tip k y) -  = case lookup k t1 of-      Just x  -> Tip k (f k x y)-      Nothing -> Nil-intersectionWithKey f Nil t = Nil-intersectionWithKey f t Nil = Nil---{---------------------------------------------------------------------  Subset---------------------------------------------------------------------}--- | /O(n+m)/. Is this a proper subset? (ie. a subset but not equal). --- Defined as (@properSubset = properSubsetBy (==)@).-properSubset :: Eq a => IntMap a -> IntMap a -> Bool-properSubset m1 m2-  = properSubsetBy (==) m1 m2--{- | /O(n+m)/. Is this a proper subset? (ie. a subset but not equal).- The expression (@properSubsetBy f m1 m2@) returns @True@ when- @m1@ and @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@.- -  > properSubsetBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])-  > properSubsetBy (<=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])-- But the following are all @False@:- -  > properSubsetBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])-  > properSubsetBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])-  > properSubsetBy (<)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])--}-properSubsetBy :: (a -> a -> Bool) -> IntMap a -> IntMap a -> Bool-properSubsetBy pred t1 t2-  = case subsetCmp pred t1 t2 of -      LT -> True-      ge -> False--subsetCmp pred t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)-  | shorter m1 m2  = GT-  | shorter m2 m1  = subsetCmpLt-  | p1 == p2       = subsetCmpEq-  | otherwise      = GT  -- disjoint-  where-    subsetCmpLt | nomatch p1 p2 m2  = GT-                | zero p1 m2        = subsetCmp pred t1 l2-                | otherwise         = subsetCmp pred t1 r2-    subsetCmpEq = case (subsetCmp pred l1 l2, subsetCmp pred r1 r2) of-                    (GT,_ ) -> GT-                    (_ ,GT) -> GT-                    (EQ,EQ) -> EQ-                    other   -> LT--subsetCmp pred (Bin p m l r) t  = GT-subsetCmp pred (Tip kx x) (Tip ky y)  -  | (kx == ky) && pred x y = EQ-  | otherwise              = GT  -- disjoint-subsetCmp pred (Tip k x) t      -  = case lookup k t of-     Just y  | pred x y -> LT-     other   -> GT -- disjoint-subsetCmp pred Nil Nil = EQ-subsetCmp pred Nil t   = LT---- | /O(n+m)/. Is this a subset? Defined as (@subset = subsetBy (==)@).-subset :: Eq a => IntMap a -> IntMap a -> Bool-subset m1 m2-  = subsetBy (==) m1 m2--{- | /O(n+m)/. - The expression (@subsetBy 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@.- -  > subsetBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])-  > subsetBy (<=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])-  > subsetBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])-- But the following are all @False@:- -  > subsetBy (==) (fromList [(1,2)]) (fromList [(1,1),(2,2)])-  > subsetBy (<) (fromList [(1,1)]) (fromList [(1,1),(2,2)])-  > subsetBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])--}--subsetBy :: (a -> a -> Bool) -> IntMap a -> IntMap a -> Bool-subsetBy pred t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)-  | shorter m1 m2  = False-  | shorter m2 m1  = match p1 p2 m2 && (if zero p1 m2 then subsetBy pred t1 l2-                                                      else subsetBy pred t1 r2)                     -  | otherwise      = (p1==p2) && subsetBy pred l1 l2 && subsetBy pred r1 r2-subsetBy pred (Bin p m l r) t  = False-subsetBy pred (Tip k x) t      = case lookup k t of-                                   Just y  -> pred x y-                                   Nothing -> False -subsetBy pred Nil t            = True--{---------------------------------------------------------------------  Mapping---------------------------------------------------------------------}--- | /O(n)/. Map a function over all values in the map.-map :: (a -> b) -> IntMap a -> IntMap b-map f m-  = mapWithKey (\k x -> f x) m---- | /O(n)/. Map a function over all values in the map.-mapWithKey :: (Key -> a -> b) -> IntMap a -> IntMap 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---- | /O(n)/. The function @mapAccum@ threads an accumulating--- argument through the map in an unspecified order.-mapAccum :: (a -> b -> (a,c)) -> a -> IntMap b -> (a,IntMap c)-mapAccum f a m-  = mapAccumWithKey (\a k x -> f a x) a m---- | /O(n)/. The function @mapAccumWithKey@ threads an accumulating--- argument through the map in an unspecified order.-mapAccumWithKey :: (a -> Key -> b -> (a,c)) -> a -> IntMap b -> (a,IntMap c)-mapAccumWithKey f a t-  = mapAccumL f a t---- | /O(n)/. The function @mapAccumL@ threads an accumulating--- argument through the map in pre-order.-mapAccumL :: (a -> Key -> b -> (a,c)) -> a -> IntMap b -> (a,IntMap c)-mapAccumL f a t-  = case t of-      Bin p m l r -> 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 @mapAccumR@ threads an accumulating--- argument throught the map in post-order.-mapAccumR :: (a -> Key -> b -> (a,c)) -> a -> IntMap b -> (a,IntMap c)-mapAccumR f a t-  = case t of-      Bin p m l r -> let (a1,r') = mapAccumR f a r-                         (a2,l') = mapAccumR 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)--{---------------------------------------------------------------------  Filter---------------------------------------------------------------------}--- | /O(n)/. Filter all values that satisfy some predicate.-filter :: (a -> Bool) -> IntMap a -> IntMap a-filter p m-  = filterWithKey (\k x -> p x) m---- | /O(n)/. Filter all keys\/values that satisfy some predicate.-filterWithKey :: (Key -> a -> Bool) -> IntMap a -> IntMap a-filterWithKey pred t-  = case t of-      Bin p m l r -        -> bin p m (filterWithKey pred l) (filterWithKey pred r)-      Tip k x -        | pred k x  -> t-        | otherwise -> Nil-      Nil -> Nil---- | /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 -> Bool) -> IntMap a -> (IntMap a,IntMap a)-partition p m-  = partitionWithKey (\k 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 :: (Key -> a -> Bool) -> IntMap a -> (IntMap a,IntMap a)-partitionWithKey pred t-  = case t of-      Bin p m l r -        -> let (l1,l2) = partitionWithKey pred l-               (r1,r2) = partitionWithKey pred r-           in (bin p m l1 r1, bin p m l2 r2)-      Tip k x -        | pred k x  -> (t,Nil)-        | otherwise -> (Nil,t)-      Nil -> (Nil,Nil)----- | /O(log n)/. 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@.-split :: Key -> IntMap a -> (IntMap a,IntMap a)-split k t-  = case t of-      Bin p m l r-        | zero k m  -> let (lt,gt) = split k l in (lt,union gt r)-        | otherwise -> let (lt,gt) = split k r in (union l lt,gt)-      Tip ky y -        | k>ky      -> (t,Nil)-        | k<ky      -> (Nil,t)-        | otherwise -> (Nil,Nil)-      Nil -> (Nil,Nil)---- | /O(log n)/. Performs a 'split' but also returns whether the pivot--- key was found in the original map.-splitLookup :: Key -> IntMap a -> (Maybe a,IntMap a,IntMap a)-splitLookup k t-  = case t of-      Bin p m l r-        | zero k m  -> let (found,lt,gt) = splitLookup k l in (found,lt,union gt r)-        | otherwise -> let (found,lt,gt) = splitLookup k r in (found,union l lt,gt)-      Tip ky y -        | k>ky      -> (Nothing,t,Nil)-        | k<ky      -> (Nothing,Nil,t)-        | otherwise -> (Just y,Nil,Nil)-      Nil -> (Nothing,Nil,Nil)--{---------------------------------------------------------------------  Fold---------------------------------------------------------------------}--- | /O(n)/. Fold over the elements of a map in an unspecified order.------ > sum map   = fold (+) 0 map--- > elems map = fold (:) [] map-fold :: (a -> b -> b) -> b -> IntMap a -> b-fold f z t-  = foldWithKey (\k x y -> f x y) z t---- | /O(n)/. Fold over the elements of a map in an unspecified order.------ > keys map = foldWithKey (\k x ks -> k:ks) [] map-foldWithKey :: (Key -> a -> b -> b) -> b -> IntMap a -> b-foldWithKey f z t-  = foldR f z t--foldR :: (Key -> a -> b -> b) -> b -> IntMap a -> b-foldR f z t-  = case t of-      Bin p m l r -> foldR f (foldR f z r) l-      Tip k x     -> f k x z-      Nil         -> z--{---------------------------------------------------------------------  List variations ---------------------------------------------------------------------}--- | /O(n)/. Return all elements of the map.-elems :: IntMap a -> [a]-elems m-  = foldWithKey (\k x xs -> x:xs) [] m  ---- | /O(n)/. Return all keys of the map.-keys  :: IntMap a -> [Key]-keys m-  = foldWithKey (\k x ks -> k:ks) [] m---- | /O(n)/. Return all key\/value pairs in the map.-assocs :: IntMap a -> [(Key,a)]-assocs m-  = toList m---{---------------------------------------------------------------------  Lists ---------------------------------------------------------------------}--- | /O(n)/. Convert the map to a list of key\/value pairs.-toList :: IntMap a -> [(Key,a)]-toList t-  = foldWithKey (\k x xs -> (k,x):xs) [] t---- | /O(n)/. Convert the map to a list of key\/value pairs where the--- keys are in ascending order.-toAscList :: IntMap a -> [(Key,a)]-toAscList t   -  = -- NOTE: the following algorithm only works for big-endian trees-    let (pos,neg) = span (\(k,x) -> k >=0) (foldR (\k x xs -> (k,x):xs) [] t) in neg ++ pos---- | /O(n*min(n,W))/. Create a map from a list of key\/value pairs.-fromList :: [(Key,a)] -> IntMap a-fromList xs-  = foldlStrict 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 :: (a -> a -> a) -> [(Key,a)] -> IntMap a -fromListWith f xs-  = fromListWithKey (\k 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'.-fromListWithKey :: (Key -> a -> a -> a) -> [(Key,a)] -> IntMap a -fromListWithKey f xs -  = foldlStrict ins empty xs-  where-    ins t (k,x) = insertWithKey f k x t---- | /O(n*min(n,W))/. Build a map from a list of key\/value pairs where--- the keys are in ascending order.-fromAscList :: [(Key,a)] -> IntMap a-fromAscList xs-  = fromList xs---- | /O(n*min(n,W))/. Build a map from a list of key\/value pairs where--- the keys are in ascending order, with a combining function on equal keys.-fromAscListWith :: (a -> a -> a) -> [(Key,a)] -> IntMap a-fromAscListWith f xs-  = fromListWith f xs---- | /O(n*min(n,W))/. Build a map from a list of key\/value pairs where--- the keys are in ascending order, with a combining function on equal keys.-fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key,a)] -> IntMap a-fromAscListWithKey f xs-  = fromListWithKey f xs---- | /O(n*min(n,W))/. Build a map from a list of key\/value pairs where--- the keys are in ascending order and all distinct.-fromDistinctAscList :: [(Key,a)] -> IntMap a-fromDistinctAscList xs-  = fromList xs---{---------------------------------------------------------------------  Eq ---------------------------------------------------------------------}-instance Eq a => Eq (IntMap a) where-  t1 == t2  = equal t1 t2-  t1 /= t2  = nequal t1 t2--equal :: Eq a => IntMap a -> IntMap 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 t1 t2   = False--nequal :: Eq a => IntMap a -> IntMap 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 t1 t2   = True--instance Show a => Show (IntMap a) where-  showsPrec d t   = showMap (toList t)---showMap :: (Show a) => [(Key,a)] -> ShowS-showMap []     -  = showString "{}" -showMap (x:xs) -  = showChar '{' . showElem x . showTail xs-  where-    showTail []     = showChar '}'-    showTail (x:xs) = showChar ',' . showElem x . showTail xs-    -    showElem (k,x)  = shows k . showString ":=" . shows x-  -{---------------------------------------------------------------------  Debugging---------------------------------------------------------------------}--- | /O(n)/. Show the tree that implements the map. The tree is shown--- in a compressed, hanging format.-showTree :: Show a => IntMap a -> String-showTree s-  = showTreeWith True False s---{- | /O(n)/. 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 -> IntMap a -> String-showTreeWith hang wide t-  | hang      = (showsTreeHang wide [] t) ""-  | otherwise = (showsTree wide [] [] t) ""--showsTree :: Show a => Bool -> [String] -> [String] -> IntMap 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] -> IntMap 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 p m-  = "*" -- ++ show (p,m)--showWide wide bars -  | wide      = showString (concat (reverse bars)) . showString "|\n" -  | otherwise = id--showsBars :: [String] -> ShowS-showsBars bars-  = case bars of-      [] -> id-      _  -> showString (concat (reverse (tail bars))) . showString node--node           = "+--"-withBar bars   = "|  ":bars-withEmpty bars = "   ":bars---{---------------------------------------------------------------------  Helpers---------------------------------------------------------------------}-{---------------------------------------------------------------------  Join---------------------------------------------------------------------}-join :: Prefix -> IntMap a -> Prefix -> IntMap a -> IntMap a-join p1 t1 p2 t2-  | zero p1 m = Bin p m t1 t2-  | otherwise = Bin p m t2 t1-  where-    m = branchMask p1 p2-    p = mask p1 m--{---------------------------------------------------------------------  @bin@ assures that we never have empty trees within a tree.---------------------------------------------------------------------}-bin :: Prefix -> Mask -> IntMap a -> IntMap a -> IntMap a-bin p m l Nil = l-bin p m Nil r = r-bin p m l r   = Bin p m l r--  -{---------------------------------------------------------------------  Endian independent bit twiddling---------------------------------------------------------------------}-zero :: Key -> Mask -> Bool-zero i m-  = (natFromInt i) .&. (natFromInt m) == 0--nomatch,match :: Key -> Prefix -> Mask -> Bool-nomatch i p m-  = (mask i m) /= p--match i p m-  = (mask i m) == p--mask :: Key -> Mask -> Prefix-mask i m-  = maskW (natFromInt i) (natFromInt m)---{---------------------------------------------------------------------  Big endian operations  ---------------------------------------------------------------------}-maskW :: Nat -> Nat -> Prefix-maskW i m-  = intFromNat (i .&. (complement (m-1) `xor` m))--shorter :: Mask -> Mask -> Bool-shorter m1 m2-  = (natFromInt m1) > (natFromInt m2)--branchMask :: Prefix -> Prefix -> Mask-branchMask p1 p2-  = intFromNat (highestBitMask (natFromInt p1 `xor` natFromInt p2))-  -{-----------------------------------------------------------------------  Finding the highest bit (mask) in a word [x] can be done efficiently in-  three ways:-  * convert to a floating point value and the mantissa tells us the -    [log2(x)] that corresponds with the highest bit position. The mantissa -    is retrieved either via the standard C function [frexp] or by some bit -    twiddling on IEEE compatible numbers (float). Note that one needs to -    use at least [double] precision for an accurate mantissa of 32 bit -    numbers.-  * use bit twiddling, a logarithmic sequence of bitwise or's and shifts (bit).-  * use processor specific assembler instruction (asm).--  The most portable way would be [bit], but is it efficient enough?-  I have measured the cycle counts of the different methods on an AMD -  Athlon-XP 1800 (~ Pentium III 1.8Ghz) using the RDTSC instruction:--  highestBitMask: method  cycles-                  ---------------                   frexp   200-                   float    33-                   bit      11-                   asm      12--  highestBit:     method  cycles-                  ---------------                   frexp   195-                   float    33-                   bit      11-                   asm      11--  Wow, the bit twiddling is on today's RISC like machines even faster-  than a single CISC instruction (BSR)!-----------------------------------------------------------------------}--{-----------------------------------------------------------------------  [highestBitMask] returns a word where only the highest bit is set.-  It is found by first setting all bits in lower positions than the -  highest bit and than taking an exclusive or with the original value.-  Allthough the function may look expensive, GHC compiles this into-  excellent C code that subsequently compiled into highly efficient-  machine code. The algorithm is derived from Jorg Arndt's FXT library.-----------------------------------------------------------------------}-highestBitMask :: Nat -> Nat-highestBitMask x-  = case (x .|. shiftRL x 1) of -     x -> case (x .|. shiftRL x 2) of -      x -> case (x .|. shiftRL x 4) of -       x -> case (x .|. shiftRL x 8) of -        x -> case (x .|. shiftRL x 16) of -         x -> case (x .|. shiftRL x 32) of   -- for 64 bit platforms-          x -> (x `xor` (shiftRL x 1))---{---------------------------------------------------------------------  Utilities ---------------------------------------------------------------------}-foldlStrict f z xs-  = case xs of-      []     -> z-      (x:xx) -> let z' = f z x in seq z' (foldlStrict f z' xx)--{--{---------------------------------------------------------------------  Testing---------------------------------------------------------------------}-testTree :: [Int] -> IntMap Int-testTree xs   = fromList [(x,x*x*30696 `mod` 65521) | x <- xs]-test1 = testTree [1..20]-test2 = testTree [30,29..10]-test3 = testTree [1,4,6,89,2323,53,43,234,5,79,12,9,24,9,8,423,8,42,4,8,9,3]--{---------------------------------------------------------------------  QuickCheck---------------------------------------------------------------------}-qcheck prop-  = check config prop-  where-    config = Config-      { configMaxTest = 500-      , configMaxFail = 5000-      , configSize    = \n -> (div n 2 + 3)-      , configEvery   = \n args -> let s = show n in s ++ [ '\b' | _ <- s ]-      }---{---------------------------------------------------------------------  Arbitrary, reasonably balanced trees---------------------------------------------------------------------}-instance Arbitrary a => Arbitrary (IntMap a) where-  arbitrary = do{ ks <- arbitrary-                ; xs <- mapM (\k -> do{ x <- arbitrary; return (k,x)}) ks-                ; return (fromList xs)-                }---{---------------------------------------------------------------------  Single, Insert, Delete---------------------------------------------------------------------}-prop_Single :: Key -> Int -> Bool-prop_Single k x-  = (insert k x empty == single k x)--prop_InsertDelete :: Key -> Int -> IntMap Int -> Property-prop_InsertDelete k x t-  = not (member k t) ==> delete k (insert k x t) == t--prop_UpdateDelete :: Key -> IntMap Int -> Bool  -prop_UpdateDelete k t-  = update (const Nothing) k t == delete k t---{---------------------------------------------------------------------  Union---------------------------------------------------------------------}-prop_UnionInsert :: Key -> Int -> IntMap Int -> Bool-prop_UnionInsert k x t-  = union (single k x) t == insert k x t--prop_UnionAssoc :: IntMap Int -> IntMap Int -> IntMap Int -> Bool-prop_UnionAssoc t1 t2 t3-  = union t1 (union t2 t3) == union (union t1 t2) t3--prop_UnionComm :: IntMap Int -> IntMap Int -> Bool-prop_UnionComm t1 t2-  = (union t1 t2 == unionWith (\x y -> y) t2 t1)---prop_Diff :: [(Key,Int)] -> [(Key,Int)] -> Bool-prop_Diff xs ys-  =  List.sort (keys (difference (fromListWith (+) xs) (fromListWith (+) ys))) -    == List.sort ((List.\\) (nub (Prelude.map fst xs))  (nub (Prelude.map fst ys)))--prop_Int :: [(Key,Int)] -> [(Key,Int)] -> Bool-prop_Int xs ys-  =  List.sort (keys (intersection (fromListWith (+) xs) (fromListWith (+) ys))) -    == List.sort (nub ((List.intersect) (Prelude.map fst xs)  (Prelude.map fst ys)))--{---------------------------------------------------------------------  Lists---------------------------------------------------------------------}-prop_Ordered-  = forAll (choose (5,100)) $ \n ->-    let xs = [(x,()) | x <- [0..n::Int]] -    in fromAscList xs == fromList xs--prop_List :: [Key] -> Bool-prop_List xs-  = (sort (nub xs) == [x | (x,()) <- toAscList (fromList [(x,()) | x <- xs])])--}
− src/UU/DData/IntSet.hs
@@ -1,852 +0,0 @@-{-# OPTIONS -cpp -fglasgow-exts #-}----------------------------------------------------------------------------------{-| Module      :  IntSet-    Copyright   :  (c) Daan Leijen 2002-    License     :  BSD-style--    Maintainer  :  daan@cs.uu.nl-    Stability   :  provisional-    Portability :  portable--  An efficient implementation of integer sets.-  -  1) The 'filter' function clashes with the "Prelude". -      If you want to use "IntSet" unqualified, this function should be hidden.--      > import Prelude hiding (filter)-      > import IntSet--      Another solution is to use qualified names. --      > import qualified IntSet-      >-      > ... IntSet.fromList [1..5]--      Or, if you prefer a terse coding style:--      > import qualified IntSet as S-      >-      > ... S.fromList [1..5]--  2) 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 "Set").-   -  *  Chris Okasaki and Andy Gill,  \"/Fast Mergeable Integer Maps/\",-     Workshop on ML, September 1998, pages 77--86, <http://www.cse.ogi.edu/~andy/pub/finite.htm>--  *  D.R. Morrison, \"/PATRICIA -- Practical Algorithm To Retrieve Information-     Coded In Alphanumeric/\", Journal of the ACM, 15(4), October 1968, pages 514--534.--  3) 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). --}----------------------------------------------------------------------------------}-module UU.DData.IntSet  ( -            -- * Set type-              IntSet          -- instance Eq,Show--            -- * Operators-            , (\\)--            -- * Query-            , isEmpty-            , size-            , member-            , subset-            , properSubset-            -            -- * Construction-            , empty-            , single-            , insert-            , delete-            -            -- * Combine-            , union, unions-            , difference-            , intersection-            -            -- * Filter-            , filter-            , partition-            , split-            , splitMember--            -- * Fold-            , fold--            -- * Conversion-            -- ** List-            , elems-            , toList-            , fromList-            -            -- ** Ordered list-            , toAscList-            , fromAscList-            , fromDistinctAscList-                        -            -- * Debugging-            , showTree-            , showTreeWith-            ) where---import Prelude hiding (lookup,filter)-import Bits -import Int--{---- just for testing-import QuickCheck -import List (nub,sort)-import qualified List--}---#ifdef __GLASGOW_HASKELL__-{---------------------------------------------------------------------  GHC: use unboxing to get @shiftRL@ inlined.---------------------------------------------------------------------}-#if __GLASGOW_HASKELL__ >= 503-import GHC.Word-import GHC.Exts ( Word(..), Int(..), shiftRL# )-#else-import Word-import GlaExts ( Word(..), Int(..), shiftRL# )-#endif---type Nat = Word--natFromInt :: Int -> Nat-natFromInt i = fromIntegral i--intFromNat :: Nat -> Int-intFromNat w = fromIntegral w--shiftRL :: Nat -> Int -> Nat-shiftRL (W# x) (I# i)-  = W# (shiftRL# x i)--#elif __HUGS__-{--------------------------------------------------------------------- Hugs: - * raises errors on boundary values when using 'fromIntegral'-   but not with the deprecated 'fromInt/toInt'. - * Older Hugs doesn't define 'Word'.- * Newer Hugs defines 'Word' in the Prelude but no operations.---------------------------------------------------------------------}-import Word--type Nat = Word32   -- illegal on 64-bit platforms!--natFromInt :: Int -> Nat-natFromInt i = fromInt i--intFromNat :: Nat -> Int-intFromNat w = toInt w--shiftRL :: Nat -> Int -> Nat-shiftRL x i   = shiftR x i--#else-{---------------------------------------------------------------------  'Standard' Haskell-  * A "Nat" is a natural machine word (an unsigned Int)---------------------------------------------------------------------}-import Word--type Nat = Word--natFromInt :: Int -> Nat-natFromInt i = fromIntegral i--intFromNat :: Nat -> Int-intFromNat w = fromIntegral w--shiftRL :: Nat -> Int -> Nat-shiftRL w i   = shiftR w i--#endif--infixl 9 \\ ----{---------------------------------------------------------------------  Operators---------------------------------------------------------------------}--- | /O(n+m)/. See 'difference'.-(\\) :: IntSet -> IntSet -> IntSet-m1 \\ m2 = difference m1 m2--{---------------------------------------------------------------------  Types  ---------------------------------------------------------------------}--- | A set of integers.-data IntSet = Nil-            | Tip !Int-            | Bin !Prefix !Mask !IntSet !IntSet--type Prefix = Int-type Mask   = Int--{---------------------------------------------------------------------  Query---------------------------------------------------------------------}--- | /O(1)/. Is the set empty?-isEmpty :: IntSet -> Bool-isEmpty Nil   = True-isEmpty other = False---- | /O(n)/. Cardinality of the set.-size :: IntSet -> Int-size t-  = case t of-      Bin p m l r -> size l + size r-      Tip y -> 1-      Nil   -> 0---- | /O(min(n,W))/. Is the value a member of the set?-member :: Int -> IntSet -> Bool-member x t-  = case t of-      Bin p m l r -        | nomatch x p m -> False-        | zero x m      -> member x l-        | otherwise     -> member x r-      Tip y -> (x==y)-      Nil   -> False-    --- 'lookup' is used by 'intersection' for left-biasing-lookup :: Int -> IntSet -> Maybe Int-lookup x t-  = case t of-      Bin p m l r -        | nomatch x p m -> Nothing-        | zero x m      -> lookup x l-        | otherwise     -> lookup x r-      Tip y -        | (x==y)    -> Just y-        | otherwise -> Nothing-      Nil -> Nothing--{---------------------------------------------------------------------  Construction---------------------------------------------------------------------}--- | /O(1)/. The empty set.-empty :: IntSet-empty-  = Nil---- | /O(1)/. A set of one element.-single :: Int -> IntSet-single x-  = Tip x--{---------------------------------------------------------------------  Insert---------------------------------------------------------------------}--- | /O(min(n,W))/. Add a value to the set. When the value is already--- an element of the set, it is replaced by the new one, ie. 'insert'--- is left-biased.-insert :: Int -> IntSet -> IntSet-insert x t-  = case t of-      Bin p m l r -        | nomatch x p m -> join x (Tip x) p t-        | zero x m      -> Bin p m (insert x l) r-        | otherwise     -> Bin p m l (insert x r)-      Tip y -        | x==y          -> Tip x-        | otherwise     -> join x (Tip x) y t-      Nil -> Tip x---- right-biased insertion, used by 'union'-insertR :: Int -> IntSet -> IntSet-insertR x t-  = case t of-      Bin p m l r -        | nomatch x p m -> join x (Tip x) p t-        | zero x m      -> Bin p m (insert x l) r-        | otherwise     -> Bin p m l (insert x r)-      Tip y -        | x==y          -> t-        | otherwise     -> join x (Tip x) y t-      Nil -> Tip x---- | /O(min(n,W))/. Delete a value in the set. Returns the--- original set when the value was not present.-delete :: Int -> IntSet -> IntSet-delete x t-  = case t of-      Bin p m l r -        | nomatch x p m -> t-        | zero x m      -> bin p m (delete x l) r-        | otherwise     -> bin p m l (delete x r)-      Tip y -        | x==y          -> Nil-        | otherwise     -> t-      Nil -> Nil---{---------------------------------------------------------------------  Union---------------------------------------------------------------------}--- | The union of a list of sets.-unions :: [IntSet] -> IntSet-unions xs-  = foldlStrict union empty xs----- | /O(n+m)/. The union of two sets. -union :: IntSet -> IntSet -> IntSet-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      = join p1 t1 p2 t2-  where-    union1  | nomatch p2 p1 m1  = join 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  = join p1 t1 p2 t2-            | zero p1 m2        = Bin p2 m2 (union t1 l2) r2-            | otherwise         = Bin p2 m2 l2 (union t1 r2)--union (Tip x) t = insert x t-union t (Tip x) = insertR x t  -- right bias-union Nil t     = t-union t Nil     = t---{---------------------------------------------------------------------  Difference---------------------------------------------------------------------}--- | /O(n+m)/. Difference between two sets. -difference :: IntSet -> IntSet -> IntSet-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 t1@(Tip x) t2 -  | member x t2  = Nil-  | otherwise    = t1--difference Nil t     = Nil-difference t (Tip x) = delete x t-difference t Nil     = t----{---------------------------------------------------------------------  Intersection---------------------------------------------------------------------}--- | /O(n+m)/. The intersection of two sets. -intersection :: IntSet -> IntSet -> IntSet-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@(Tip x) t2 -  | member x t2  = t1-  | otherwise    = Nil-intersection t (Tip x) -  = case lookup x t of-      Just y  -> Tip y-      Nothing -> Nil-intersection Nil t = Nil-intersection t Nil = Nil----{---------------------------------------------------------------------  Subset---------------------------------------------------------------------}--- | /O(n+m)/. Is this a proper subset? (ie. a subset but not equal).-properSubset :: IntSet -> IntSet -> Bool-properSubset t1 t2-  = case subsetCmp t1 t2 of -      LT -> True-      ge -> False--subsetCmp t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)-  | shorter m1 m2  = GT-  | shorter m2 m1  = subsetCmpLt-  | 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-                    other   -> LT--subsetCmp (Bin p m l r) t  = GT-subsetCmp (Tip x) (Tip y)  -  | x==y       = EQ-  | otherwise  = GT  -- disjoint-subsetCmp (Tip x) t        -  | member x t = LT-  | otherwise  = GT  -- disjoint-subsetCmp Nil Nil = EQ-subsetCmp Nil t   = LT---- | /O(n+m)/. Is this a subset?-subset :: IntSet -> IntSet -> Bool-subset t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)-  | shorter m1 m2  = False-  | shorter m2 m1  = match p1 p2 m2 && (if zero p1 m2 then subset t1 l2-                                                      else subset t1 r2)                     -  | otherwise      = (p1==p2) && subset l1 l2 && subset r1 r2-subset (Bin p m l r) t  = False-subset (Tip x) t        = member x t-subset Nil t            = True---{---------------------------------------------------------------------  Filter---------------------------------------------------------------------}--- | /O(n)/. Filter all elements that satisfy some predicate.-filter :: (Int -> Bool) -> IntSet -> IntSet-filter pred t-  = case t of-      Bin p m l r -        -> bin p m (filter pred l) (filter pred r)-      Tip x -        | pred x    -> t-        | otherwise -> Nil-      Nil -> Nil---- | /O(n)/. partition the set according to some predicate.-partition :: (Int -> Bool) -> IntSet -> (IntSet,IntSet)-partition pred t-  = case t of-      Bin p m l r -        -> let (l1,l2) = partition pred l-               (r1,r2) = partition pred r-           in (bin p m l1 r1, bin p m l2 r2)-      Tip x -        | pred x    -> (t,Nil)-        | otherwise -> (Nil,t)-      Nil -> (Nil,Nil)----- | /O(log n)/. The expression (@split x set@) is a pair @(set1,set2)@--- where all elements in @set1@ are lower than @x@ and all elements in--- @set2@ larger than @x@.-split :: Int -> IntSet -> (IntSet,IntSet)-split x t-  = case t of-      Bin p m l r-        | zero x m  -> let (lt,gt) = split x l in (lt,union gt r)-        | otherwise -> let (lt,gt) = split x r in (union l lt,gt)-      Tip y -        | x>y       -> (t,Nil)-        | x<y       -> (Nil,t)-        | otherwise -> (Nil,Nil)-      Nil -> (Nil,Nil)---- | /O(log n)/. Performs a 'split' but also returns whether the pivot--- element was found in the original set.-splitMember :: Int -> IntSet -> (Bool,IntSet,IntSet)-splitMember x t-  = case t of-      Bin p m l r-        | zero x m  -> let (found,lt,gt) = splitMember x l in (found,lt,union gt r)-        | otherwise -> let (found,lt,gt) = splitMember x r in (found,union l lt,gt)-      Tip y -        | x>y       -> (False,t,Nil)-        | x<y       -> (False,Nil,t)-        | otherwise -> (True,Nil,Nil)-      Nil -> (False,Nil,Nil)---{---------------------------------------------------------------------  Fold---------------------------------------------------------------------}--- | /O(n)/. Fold over the elements of a set in an unspecified order.------ > sum set   = fold (+) 0 set--- > elems set = fold (:) [] set-fold :: (Int -> b -> b) -> b -> IntSet -> b-fold f z t-  = foldR f z t--foldR :: (Int -> b -> b) -> b -> IntSet -> b-foldR f z t-  = case t of-      Bin p m l r -> foldR f (foldR f z r) l-      Tip x       -> f x z-      Nil         -> z-          -{---------------------------------------------------------------------  List variations ---------------------------------------------------------------------}--- | /O(n)/. The elements of a set.-elems :: IntSet -> [Int]-elems s-  = toList s--{---------------------------------------------------------------------  Lists ---------------------------------------------------------------------}--- | /O(n)/. Convert the set to a list of elements.-toList :: IntSet -> [Int]-toList t-  = fold (:) [] t---- | /O(n)/. Convert the set to an ascending list of elements.-toAscList :: IntSet -> [Int]-toAscList t   -  = -- NOTE: the following algorithm only works for big-endian trees-    let (pos,neg) = span (>=0) (foldR (:) [] t) in neg ++ pos---- | /O(n*min(n,W))/. Create a set from a list of integers.-fromList :: [Int] -> IntSet-fromList xs-  = foldlStrict ins empty xs-  where-    ins t x  = insert x t---- | /O(n*min(n,W))/. Build a set from an ascending list of elements.-fromAscList :: [Int] -> IntSet -fromAscList xs-  = fromList xs---- | /O(n*min(n,W))/. Build a set from an ascending list of distinct elements.-fromDistinctAscList :: [Int] -> IntSet-fromDistinctAscList xs-  = fromList xs---{---------------------------------------------------------------------  Eq ---------------------------------------------------------------------}-instance Eq IntSet where-  t1 == t2  = equal t1 t2-  t1 /= t2  = nequal t1 t2--equal :: IntSet -> IntSet -> Bool-equal (Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)-  = (m1 == m2) && (p1 == p2) && (equal l1 l2) && (equal r1 r2) -equal (Tip x) (Tip y)-  = (x==y)-equal Nil Nil = True-equal t1 t2   = False--nequal :: IntSet -> IntSet -> Bool-nequal (Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)-  = (m1 /= m2) || (p1 /= p2) || (nequal l1 l2) || (nequal r1 r2) -nequal (Tip x) (Tip y)-  = (x/=y)-nequal Nil Nil = False-nequal t1 t2   = True--{---------------------------------------------------------------------  Show---------------------------------------------------------------------}-instance Show IntSet where-  showsPrec d s  = showSet (toList s)--showSet :: [Int] -> ShowS-showSet []     -  = showString "{}" -showSet (x:xs) -  = showChar '{' . shows x . showTail xs-  where-    showTail []     = showChar '}'-    showTail (x:xs) = showChar ',' . shows x . showTail xs--{---------------------------------------------------------------------  Debugging---------------------------------------------------------------------}--- | /O(n)/. Show the tree that implements the set. The tree is shown--- in a compressed, hanging format.-showTree :: IntSet -> String-showTree s-  = showTreeWith True False s---{- | /O(n)/. 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 -> IntSet -> String-showTreeWith hang wide t-  | hang      = (showsTreeHang wide [] t) ""-  | otherwise = (showsTree wide [] [] t) ""--showsTree :: Bool -> [String] -> [String] -> IntSet -> 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 x-          -> showsBars lbars . showString " " . shows x . showString "\n" -      Nil -> showsBars lbars . showString "|\n"--showsTreeHang :: Bool -> [String] -> IntSet -> 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 x-          -> showsBars bars . showString " " . shows x . showString "\n" -      Nil -> showsBars bars . showString "|\n" -      -showBin p m-  = "*" -- ++ show (p,m)--showWide wide bars -  | wide      = showString (concat (reverse bars)) . showString "|\n" -  | otherwise = id--showsBars :: [String] -> ShowS-showsBars bars-  = case bars of-      [] -> id-      _  -> showString (concat (reverse (tail bars))) . showString node--node           = "+--"-withBar bars   = "|  ":bars-withEmpty bars = "   ":bars---{---------------------------------------------------------------------  Helpers---------------------------------------------------------------------}-{---------------------------------------------------------------------  Join---------------------------------------------------------------------}-join :: Prefix -> IntSet -> Prefix -> IntSet -> IntSet-join p1 t1 p2 t2-  | zero p1 m = Bin p m t1 t2-  | otherwise = Bin p m t2 t1-  where-    m = branchMask p1 p2-    p = mask p1 m--{---------------------------------------------------------------------  @bin@ assures that we never have empty trees within a tree.---------------------------------------------------------------------}-bin :: Prefix -> Mask -> IntSet -> IntSet -> IntSet-bin p m l Nil = l-bin p m Nil r = r-bin p m l r   = Bin p m l r--  -{---------------------------------------------------------------------  Endian independent bit twiddling---------------------------------------------------------------------}-zero :: Int -> Mask -> Bool-zero i m-  = (natFromInt i) .&. (natFromInt m) == 0--nomatch,match :: Int -> Prefix -> Mask -> Bool-nomatch i p m-  = (mask i m) /= p--match i p m-  = (mask i m) == p--mask :: Int -> Mask -> Prefix-mask i m-  = maskW (natFromInt i) (natFromInt m)---{---------------------------------------------------------------------  Big endian operations  ---------------------------------------------------------------------}-maskW :: Nat -> Nat -> Prefix-maskW i m-  = intFromNat (i .&. (complement (m-1) `xor` m))--shorter :: Mask -> Mask -> Bool-shorter m1 m2-  = (natFromInt m1) > (natFromInt m2)--branchMask :: Prefix -> Prefix -> Mask-branchMask p1 p2-  = intFromNat (highestBitMask (natFromInt p1 `xor` natFromInt p2))-  -{-----------------------------------------------------------------------  Finding the highest bit (mask) in a word [x] can be done efficiently in-  three ways:-  * convert to a floating point value and the mantissa tells us the -    [log2(x)] that corresponds with the highest bit position. The mantissa -    is retrieved either via the standard C function [frexp] or by some bit -    twiddling on IEEE compatible numbers (float). Note that one needs to -    use at least [double] precision for an accurate mantissa of 32 bit -    numbers.-  * use bit twiddling, a logarithmic sequence of bitwise or's and shifts (bit).-  * use processor specific assembler instruction (asm).--  The most portable way would be [bit], but is it efficient enough?-  I have measured the cycle counts of the different methods on an AMD -  Athlon-XP 1800 (~ Pentium III 1.8Ghz) using the RDTSC instruction:--  highestBitMask: method  cycles-                  ---------------                   frexp   200-                   float    33-                   bit      11-                   asm      12--  highestBit:     method  cycles-                  ---------------                   frexp   195-                   float    33-                   bit      11-                   asm      11--  Wow, the bit twiddling is on today's RISC like machines even faster-  than a single CISC instruction (BSR)!-----------------------------------------------------------------------}--{-----------------------------------------------------------------------  [highestBitMask] returns a word where only the highest bit is set.-  It is found by first setting all bits in lower positions than the -  highest bit and than taking an exclusive or with the original value.-  Allthough the function may look expensive, GHC compiles this into-  excellent C code that subsequently compiled into highly efficient-  machine code. The algorithm is derived from Jorg Arndt's FXT library.-----------------------------------------------------------------------}-highestBitMask :: Nat -> Nat-highestBitMask x-  = case (x .|. shiftRL x 1) of -     x -> case (x .|. shiftRL x 2) of -      x -> case (x .|. shiftRL x 4) of -       x -> case (x .|. shiftRL x 8) of -        x -> case (x .|. shiftRL x 16) of -         x -> case (x .|. shiftRL x 32) of   -- for 64 bit platforms-          x -> (x `xor` (shiftRL x 1))---{---------------------------------------------------------------------  Utilities ---------------------------------------------------------------------}-foldlStrict f z xs-  = case xs of-      []     -> z-      (x:xx) -> let z' = f z x in seq z' (foldlStrict f z' xx)---{--{---------------------------------------------------------------------  Testing---------------------------------------------------------------------}-testTree :: [Int] -> IntSet-testTree xs   = fromList xs-test1 = testTree [1..20]-test2 = testTree [30,29..10]-test3 = testTree [1,4,6,89,2323,53,43,234,5,79,12,9,24,9,8,423,8,42,4,8,9,3]--{---------------------------------------------------------------------  QuickCheck---------------------------------------------------------------------}-qcheck prop-  = check config prop-  where-    config = Config-      { configMaxTest = 500-      , configMaxFail = 5000-      , configSize    = \n -> (div n 2 + 3)-      , configEvery   = \n args -> let s = show n in s ++ [ '\b' | _ <- s ]-      }---{---------------------------------------------------------------------  Arbitrary, reasonably balanced trees---------------------------------------------------------------------}-instance Arbitrary IntSet where-  arbitrary = do{ xs <- arbitrary-                ; return (fromList xs)-                }---{---------------------------------------------------------------------  Single, Insert, Delete---------------------------------------------------------------------}-prop_Single :: Int -> Bool-prop_Single x-  = (insert x empty == single x)--prop_InsertDelete :: Int -> IntSet -> Property-prop_InsertDelete k t-  = not (member k t) ==> delete k (insert k t) == t---{---------------------------------------------------------------------  Union---------------------------------------------------------------------}-prop_UnionInsert :: Int -> IntSet -> Bool-prop_UnionInsert x t-  = union t (single x) == insert x t--prop_UnionAssoc :: IntSet -> IntSet -> IntSet -> Bool-prop_UnionAssoc t1 t2 t3-  = union t1 (union t2 t3) == union (union t1 t2) t3--prop_UnionComm :: IntSet -> IntSet -> Bool-prop_UnionComm t1 t2-  = (union t1 t2 == union t2 t1)--prop_Diff :: [Int] -> [Int] -> Bool-prop_Diff xs ys-  =  toAscList (difference (fromList xs) (fromList ys))-    == List.sort ((List.\\) (nub xs)  (nub ys))--prop_Int :: [Int] -> [Int] -> Bool-prop_Int xs ys-  =  toAscList (intersection (fromList xs) (fromList ys))-    == List.sort (nub ((List.intersect) (xs)  (ys)))--{---------------------------------------------------------------------  Lists---------------------------------------------------------------------}-prop_Ordered-  = forAll (choose (5,100)) $ \n ->-    let xs = [0..n::Int]-    in fromAscList xs == fromList xs--prop_List :: [Int] -> Bool-prop_List xs-  = (sort (nub xs) == toAscList (fromList xs))--}-
− src/UU/DData/Map.hs
@@ -1,1544 +0,0 @@----------------------------------------------------------------------------------{-| Module      :  Map-    Copyright   :  (c) Daan Leijen 2002-    License     :  BSD-style--    Maintainer  :  daan@cs.uu.nl-    Stability   :  provisional-    Portability :  portable--  An efficient implementation of maps from keys to values (dictionaries). --  1) The module exports some names that clash with the "Prelude" -- 'lookup', 'map', and 'filter'. -      If you want to use "Map" unqualified, these functions should be hidden.--      > import Prelude hiding (lookup,map,filter)-      > import Map--      Another solution is to use qualified names. This is also the only way how-      a "Map", "Set", and "MultiSet" can be used within one module. --      > import qualified Map-      >-      > ... Map.single "Paris" "France"--      Or, if you prefer a terse coding style:--      > import qualified Map as M-      >-      > ... M.single "Berlin" "Germany"--  2) The implementation of "Map" is based on /size balanced/ binary trees (or-     trees of /bounded balance/) as described by:--     * Stephen Adams, \"/Efficient sets: a balancing act/\", Journal of Functional-       Programming 3(4):553-562, October 1993, <http://www.swiss.ai.mit.edu/~adams/BB>.--     * J. Nievergelt and E.M. Reingold, \"/Binary search trees of bounded balance/\",-       SIAM journal of computing 2(1), March 1973.-     -  3) Another implementation of finite maps based on size balanced trees-      exists as "Data.FiniteMap" in the Ghc libraries. The good part about this library -      is that it is highly tuned and thorougly tested. However, it is also fairly old, -      uses @#ifdef@'s all  over the place and only supports the basic finite map operations. -      The "Map" module overcomes some of these issues:-        -      * It tries to export a more complete and consistent set of operations, like-        'partition', 'adjust', 'mapAccum', 'elemAt' etc. -      -      * It uses the efficient /hedge/ algorithm for both 'union' and 'difference'-        (a /hedge/ algorithm is not applicable to 'intersection').-      -      * It converts ordered lists in linear time ('fromAscList').  --      * It takes advantage of the module system with names like 'empty' instead of 'Data.FiniteMap.emptyFM'.-      -      * It sticks to portable Haskell, avoiding @#ifdef@'s and other magic.--}------------------------------------------------------------------------------------module UU.DData.Map  ( -            -- * Map type-              Map          -- instance Eq,Show--            -- * Operators-            , (!), (\\)--            -- * Query-            , isEmpty-            , size-            , member-            , lookup-            , find          -            , findWithDefault-            -            -- * Construction-            , empty-            , single--            -- ** Insertion-            , insert-            , insertWith, insertWithKey, insertLookupWithKey-            -            -- ** Delete\/Update-            , delete-            , adjust-            , adjustWithKey-            , update-            , updateWithKey-            , updateLookupWithKey--            -- * Combine--            -- ** Union-            , union         -            , unionWith          -            , unionWithKey-            , unions--            -- ** Difference-            , difference-            , differenceWith-            , differenceWithKey-            -            -- ** Intersection-            , intersection           -            , intersectionWith-            , intersectionWithKey--            -- * Traversal-            -- ** Map-            , map-            , mapWithKey-            , mapAccum-            , mapAccumWithKey-            -            -- ** Fold-            , fold-            , foldWithKey--            -- * Conversion-            , elems-            , keys-            , assocs-            -            -- ** Lists-            , toList-            , fromList-            , fromListWith-            , fromListWithKey--            -- ** Ordered lists-            , toAscList-            , fromAscList-            , fromAscListWith-            , fromAscListWithKey-            , fromDistinctAscList--            -- * Filter -            , filter-            , filterWithKey-            , partition-            , partitionWithKey--            , split         -            , splitLookup   --            -- * Subset-            , subset, subsetBy-            , properSubset, properSubsetBy--            -- * Indexed -            , lookupIndex-            , findIndex-            , elemAt-            , updateAt-            , deleteAt--            -- * Min\/Max-            , findMin-            , findMax-            , deleteMin-            , deleteMax-            , deleteFindMin-            , deleteFindMax-            , updateMin-            , updateMax-            , updateMinWithKey-            , updateMaxWithKey-            -            -- * Debugging-            , showTree-            , showTreeWith-            , valid-            ) where--import Prelude hiding (lookup,map,filter)---{---- for quick check-import qualified Prelude-import qualified List-import Debug.QuickCheck       -import List(nub,sort)    --}--{---------------------------------------------------------------------  Operators---------------------------------------------------------------------}-infixl 9 !,\\ ------ | /O(log n)/. See 'find'.-(!) :: Ord k => Map k a -> k -> a-(!) m k    = find k m---- | /O(n+m)/. See 'difference'.-(\\) :: Ord k => Map k a -> Map k a -> Map k a-m1 \\ m2 = difference m1 m2--{---------------------------------------------------------------------  Size balanced trees.---------------------------------------------------------------------}--- | A Map from keys @k@ and values @a@. -data Map k a  = Tip -              | Bin !Size !k a !(Map k a) !(Map k a) --type Size     = Int--{---------------------------------------------------------------------  Query---------------------------------------------------------------------}--- | /O(1)/. Is the map empty?-isEmpty :: Map k a -> Bool-isEmpty t-  = case t of-      Tip             -> True-      Bin sz k x l r  -> False---- | /O(1)/. The number of elements in the map.-size :: Map k a -> Int-size t-  = case t of-      Tip             -> 0-      Bin sz k x l r  -> sz----- | /O(log n)/. Lookup the value of key in the map.-lookup :: Ord k => k -> Map k a -> Maybe a-lookup k t-  = case t of-      Tip -> Nothing-      Bin sz kx x l r-          -> case compare k kx of-               LT -> lookup k l-               GT -> lookup k r-               EQ -> Just x       ---- | /O(log n)/. Is the key a member of the map?-member :: Ord k => k -> Map k a -> Bool-member k m-  = case lookup k m of-      Nothing -> False-      Just x  -> True---- | /O(log n)/. Find the value of a key. Calls @error@ when the element can not be found.-find :: Ord k => k -> Map k a -> a-find k m-  = case lookup k m of-      Nothing -> error "Map.find: element not in the map"-      Just x  -> x---- | /O(log n)/. The expression @(findWithDefault def k map)@ returns the value of key @k@ or returns @def@ when--- the key is not in the map.-findWithDefault :: Ord k => a -> k -> Map k a -> a-findWithDefault def k m-  = case lookup k m of-      Nothing -> def-      Just x  -> x----{---------------------------------------------------------------------  Construction---------------------------------------------------------------------}--- | /O(1)/. Create an empty map.-empty :: Map k a-empty -  = Tip---- | /O(1)/. Create a map with a single element.-single :: k -> a -> Map k a-single k x  -  = Bin 1 k x Tip Tip--{---------------------------------------------------------------------  Insertion-  [insert] is the inlined version of [insertWith (\k x y -> x)]---------------------------------------------------------------------}--- | /O(log n)/. Insert a new key and value in the map.-insert :: Ord k => k -> a -> Map k a -> Map k a-insert kx x t-  = case t of-      Tip -> single kx x-      Bin sz ky y l r-          -> case compare kx ky of-               LT -> balance ky y (insert kx x l) r-               GT -> balance ky y l (insert kx x r)-               EQ -> Bin sz kx x l r---- | /O(log n)/. Insert with a combining function.-insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a-insertWith f k x m          -  = insertWithKey (\k x y -> f x y) k x m---- | /O(log n)/. Insert with a combining function.-insertWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a-insertWithKey f kx x t-  = case t of-      Tip -> single kx x-      Bin sy ky y l r-          -> case compare kx ky of-               LT -> balance ky y (insertWithKey f kx x l) r-               GT -> balance ky y l (insertWithKey f kx x r)-               EQ -> Bin sy ky (f ky x y) l r---- | /O(log n)/. 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@).-insertLookupWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> (Maybe a,Map k a)-insertLookupWithKey f kx x t-  = case t of-      Tip -> (Nothing, single kx x)-      Bin sy ky y l r-          -> case compare kx ky of-               LT -> let (found,l') = insertLookupWithKey f kx x l in (found,balance ky y l' r)-               GT -> let (found,r') = insertLookupWithKey f kx x r in (found,balance ky y l r')-               EQ -> (Just y, Bin sy ky (f ky x y) l r)--{---------------------------------------------------------------------  Deletion-  [delete] is the inlined version of [deleteWith (\k x -> Nothing)]---------------------------------------------------------------------}--- | /O(log n)/. 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 :: Ord k => k -> Map k a -> Map k a-delete k t-  = case t of-      Tip -> Tip-      Bin sx kx x l r -          -> case compare k kx of-               LT -> balance kx x (delete k l) r-               GT -> balance kx x l (delete k r)-               EQ -> glue l r---- | /O(log n)/. Adjust a value at a specific key. When the key is not--- a member of the map, the original map is returned.-adjust :: Ord k => (a -> a) -> k -> Map k a -> Map k a-adjust f k m-  = adjustWithKey (\k x -> f x) k m---- | /O(log n)/. Adjust a value at a specific key. When the key is not--- a member of the map, the original map is returned.-adjustWithKey :: Ord k => (k -> a -> a) -> k -> Map k a -> Map k a-adjustWithKey f k m-  = updateWithKey (\k x -> Just (f k x)) k m---- | /O(log n)/. 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@.-update :: Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a-update f k m-  = updateWithKey (\k x -> f x) k m---- | /O(log n)/. 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@.-updateWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> Map k a-updateWithKey f k t-  = case t of-      Tip -> Tip-      Bin sx kx x l r -          -> case compare k kx of-               LT -> balance kx x (updateWithKey f k l) r-               GT -> balance kx x l (updateWithKey f k r)-               EQ -> case f kx x of-                       Just x' -> Bin sx kx x' l r-                       Nothing -> glue l r---- | /O(log n)/. Lookup and update.-updateLookupWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> (Maybe a,Map k a)-updateLookupWithKey f k t-  = case t of-      Tip -> (Nothing,Tip)-      Bin sx kx x l r -          -> case compare k kx of-               LT -> let (found,l') = updateLookupWithKey f k l in (found,balance kx x l' r)-               GT -> let (found,r') = updateLookupWithKey f k r in (found,balance kx x l r') -               EQ -> case f kx x of-                       Just x' -> (Just x',Bin sx kx x' l r)-                       Nothing -> (Just x,glue l r)--{---------------------------------------------------------------------  Indexing---------------------------------------------------------------------}--- | /O(log n)/. Return the /index/ of a key. The index is a number from--- /0/ up to, but not including, the 'size' of the map. Calls 'error' when--- the key is not a 'member' of the map.-findIndex :: Ord k => k -> Map k a -> Int-findIndex k t-  = case lookupIndex k t of-      Nothing  -> error "Map.findIndex: element is not in the map"-      Just idx -> idx---- | /O(log n)/. Lookup the /index/ of a key. The index is a number from--- /0/ up to, but not including, the 'size' of the map. -lookupIndex :: Ord k => k -> Map k a -> Maybe Int-lookupIndex k t-  = lookup 0 t-  where-    lookup idx Tip  = Nothing-    lookup idx (Bin _ kx x l r)-      = case compare k kx of-          LT -> lookup idx l-          GT -> lookup (idx + size l + 1) r -          EQ -> Just (idx + size l)---- | /O(log n)/. Retrieve an element by /index/. Calls 'error' when an--- invalid index is used.-elemAt :: Int -> Map k a -> (k,a)-elemAt i Tip = error "Map.elemAt: index out of range"-elemAt i (Bin _ kx x l r)-  = case compare i sizeL of-      LT -> elemAt i l-      GT -> elemAt (i-sizeL-1) r-      EQ -> (kx,x)-  where-    sizeL = size l---- | /O(log n)/. Update the element at /index/. Calls 'error' when an--- invalid index is used.-updateAt :: (k -> a -> Maybe a) -> Int -> Map k a -> Map k a-updateAt f i Tip  = error "Map.updateAt: index out of range"-updateAt f i (Bin sx kx x l r)-  = case compare i sizeL of-      LT -> updateAt f i l-      GT -> updateAt f (i-sizeL-1) r-      EQ -> case f kx x of-              Just x' -> Bin sx kx x' l r-              Nothing -> glue l r-  where-    sizeL = size l---- | /O(log n)/. Delete the element at /index/. Defined as (@deleteAt i map = updateAt (\k x -> Nothing) i map@).-deleteAt :: Int -> Map k a -> Map k a-deleteAt i map-  = updateAt (\k x -> Nothing) i map---{---------------------------------------------------------------------  Minimal, Maximal---------------------------------------------------------------------}--- | /O(log n)/. The minimal key of the map.-findMin :: Map k a -> (k,a)-findMin (Bin _ kx x Tip r)  = (kx,x)-findMin (Bin _ kx x l r)    = findMin l-findMin Tip                 = error "Map.findMin: empty tree has no minimal element"---- | /O(log n)/. The maximal key of the map.-findMax :: Map k a -> (k,a)-findMax (Bin _ kx x l Tip)  = (kx,x)-findMax (Bin _ kx x l r)    = findMax r-findMax Tip                 = error "Map.findMax: empty tree has no maximal element"---- | /O(log n)/. Delete the minimal key-deleteMin :: Map k a -> Map k a-deleteMin (Bin _ kx x Tip r)  = r-deleteMin (Bin _ kx x l r)    = balance kx x (deleteMin l) r-deleteMin Tip                 = Tip---- | /O(log n)/. Delete the maximal key-deleteMax :: Map k a -> Map k a-deleteMax (Bin _ kx x l Tip)  = l-deleteMax (Bin _ kx x l r)    = balance kx x l (deleteMax r)-deleteMax Tip                 = Tip---- | /O(log n)/. Update the minimal key-updateMin :: (a -> Maybe a) -> Map k a -> Map k a-updateMin f m-  = updateMinWithKey (\k x -> f x) m---- | /O(log n)/. Update the maximal key-updateMax :: (a -> Maybe a) -> Map k a -> Map k a-updateMax f m-  = updateMaxWithKey (\k x -> f x) m----- | /O(log n)/. Update the minimal key-updateMinWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a-updateMinWithKey f t-  = case t of-      Bin sx kx x Tip r  -> case f kx x of-                              Nothing -> r-                              Just x' -> Bin sx kx x' Tip r-      Bin sx kx x l r    -> balance kx x (updateMinWithKey f l) r-      Tip                -> Tip---- | /O(log n)/. Update the maximal key-updateMaxWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a-updateMaxWithKey f t-  = case t of-      Bin sx kx x l Tip  -> case f kx x of-                              Nothing -> l-                              Just x' -> Bin sx kx x' l Tip-      Bin sx kx x l r    -> balance kx x l (updateMaxWithKey f r)-      Tip                -> Tip---{---------------------------------------------------------------------  Union. ---------------------------------------------------------------------}--- | The union of a list of maps: (@unions == foldl union empty@).-unions :: Ord k => [Map k a] -> Map k a-unions ts-  = foldlStrict union empty ts---- | /O(n+m)/.--- The expression (@'union' t1 t2@) takes the left-biased union of @t1@ and @t2@. --- It prefers @t1@ when duplicate keys are encountered, ie. (@union == unionWith const@).--- The implementation uses the efficient /hedge-union/ algorithm.-union :: Ord k => Map k a -> Map k a -> Map k a-union Tip t2  = t2-union t1 Tip  = t1-union t1 t2  -- hedge-union is more efficient on (bigset `union` smallset)-   | size t1 >= size t2  = hedgeUnionL (const LT) (const GT) t1 t2-   | otherwise           = hedgeUnionR (const LT) (const GT) t2 t1---- left-biased hedge union-hedgeUnionL cmplo cmphi t1 Tip -  = t1-hedgeUnionL cmplo cmphi Tip (Bin _ kx x l r)-  = join kx x (filterGt cmplo l) (filterLt cmphi r)-hedgeUnionL cmplo cmphi (Bin _ kx x l r) t2-  = join kx x (hedgeUnionL cmplo cmpkx l (trim cmplo cmpkx t2)) -              (hedgeUnionL cmpkx cmphi r (trim cmpkx cmphi t2))-  where-    cmpkx k  = compare kx k---- right-biased hedge union-hedgeUnionR cmplo cmphi t1 Tip -  = t1-hedgeUnionR cmplo cmphi Tip (Bin _ kx x l r)-  = join kx x (filterGt cmplo l) (filterLt cmphi r)-hedgeUnionR cmplo cmphi (Bin _ kx x l r) t2-  = join kx newx (hedgeUnionR cmplo cmpkx l lt) -                 (hedgeUnionR cmpkx cmphi r gt)-  where-    cmpkx k     = compare kx k-    lt          = trim cmplo cmpkx t2-    (found,gt)  = trimLookupLo kx cmphi t2-    newx        = case found of-                    Nothing -> x-                    Just y  -> y--{---------------------------------------------------------------------  Union with a combining function---------------------------------------------------------------------}--- | /O(n+m)/. Union with a combining function. The implementation uses the efficient /hedge-union/ algorithm.-unionWith :: Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a-unionWith f m1 m2-  = unionWithKey (\k x y -> f x y) m1 m2---- | /O(n+m)/.--- Union with a combining function. The implementation uses the efficient /hedge-union/ algorithm.-unionWithKey :: Ord k => (k -> a -> a -> a) -> Map k a -> Map k a -> Map k a-unionWithKey f Tip t2  = t2-unionWithKey f t1 Tip  = t1-unionWithKey f t1 t2  -- hedge-union is more efficient on (bigset `union` smallset)-  | size t1 >= size t2  = hedgeUnionWithKey f (const LT) (const GT) t1 t2-  | otherwise           = hedgeUnionWithKey flipf (const LT) (const GT) t2 t1-  where-    flipf k x y   = f k y x--hedgeUnionWithKey f cmplo cmphi t1 Tip -  = t1-hedgeUnionWithKey f cmplo cmphi Tip (Bin _ kx x l r)-  = join kx x (filterGt cmplo l) (filterLt cmphi r)-hedgeUnionWithKey f cmplo cmphi (Bin _ kx x l r) t2-  = join kx newx (hedgeUnionWithKey f cmplo cmpkx l lt) -                 (hedgeUnionWithKey f cmpkx cmphi r gt)-  where-    cmpkx k     = compare kx k-    lt          = trim cmplo cmpkx t2-    (found,gt)  = trimLookupLo kx cmphi t2-    newx        = case found of-                    Nothing -> x-                    Just y  -> f kx x y--{---------------------------------------------------------------------  Difference---------------------------------------------------------------------}--- | /O(n+m)/. Difference of two maps. --- The implementation uses an efficient /hedge/ algorithm comparable with /hedge-union/.-difference :: Ord k => Map k a -> Map k a -> Map k a-difference Tip t2  = Tip-difference t1 Tip  = t1-difference t1 t2   = hedgeDiff (const LT) (const GT) t1 t2--hedgeDiff cmplo cmphi Tip t     -  = Tip-hedgeDiff cmplo cmphi (Bin _ kx x l r) Tip -  = join kx x (filterGt cmplo l) (filterLt cmphi r)-hedgeDiff cmplo cmphi t (Bin _ kx x l r) -  = merge (hedgeDiff cmplo cmpkx (trim cmplo cmpkx t) l) -          (hedgeDiff cmpkx cmphi (trim cmpkx cmphi t) r)-  where-    cmpkx k = compare kx k   ---- | /O(n+m)/. Difference with a combining function. --- The implementation uses an efficient /hedge/ algorithm comparable with /hedge-union/.-differenceWith :: Ord k => (a -> a -> Maybe a) -> Map k a -> Map k a -> Map k a-differenceWith f m1 m2-  = differenceWithKey (\k 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@. --- The implementation uses an efficient /hedge/ algorithm comparable with /hedge-union/.-differenceWithKey :: Ord k => (k -> a -> a -> Maybe a) -> Map k a -> Map k a -> Map k a-differenceWithKey f Tip t2  = Tip-differenceWithKey f t1 Tip  = t1-differenceWithKey f t1 t2   = hedgeDiffWithKey f (const LT) (const GT) t1 t2--hedgeDiffWithKey f cmplo cmphi Tip t     -  = Tip-hedgeDiffWithKey f cmplo cmphi (Bin _ kx x l r) Tip -  = join kx x (filterGt cmplo l) (filterLt cmphi r)-hedgeDiffWithKey f cmplo cmphi t (Bin _ kx x l r) -  = case found of-      Nothing -> merge tl tr-      Just y  -> case f kx y x of-                   Nothing -> merge tl tr-                   Just z  -> join kx z tl tr-  where-    cmpkx k     = compare kx k   -    lt          = trim cmplo cmpkx t-    (found,gt)  = trimLookupLo kx cmphi t-    tl          = hedgeDiffWithKey f cmplo cmpkx lt l-    tr          = hedgeDiffWithKey f cmpkx cmphi gt r----{---------------------------------------------------------------------  Intersection---------------------------------------------------------------------}--- | /O(n+m)/. Intersection of two maps. The values in the first--- map are returned, i.e. (@intersection m1 m2 == intersectionWith const m1 m2@).-intersection :: Ord k => Map k a -> Map k a -> Map k a-intersection m1 m2-  = intersectionWithKey (\k x y -> x) m1 m2---- | /O(n+m)/. Intersection with a combining function.-intersectionWith :: Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a-intersectionWith f m1 m2-  = intersectionWithKey (\k x y -> f x y) m1 m2---- | /O(n+m)/. Intersection with a combining function.-intersectionWithKey :: Ord k => (k -> a -> a -> a) -> Map k a -> Map k a -> Map k a-intersectionWithKey f Tip t = Tip-intersectionWithKey f t Tip = Tip-intersectionWithKey f t1 t2  -- intersection is more efficient on (bigset `intersection` smallset)-  | size t1 >= size t2  = intersectWithKey f t1 t2-  | otherwise           = intersectWithKey flipf t2 t1-  where-    flipf k x y   = f k y x--intersectWithKey f Tip t = Tip-intersectWithKey f t Tip = Tip-intersectWithKey f t (Bin _ kx x l r)-  = case found of-      Nothing -> merge tl tr-      Just y  -> join kx (f kx y x) tl tr-  where-    (found,lt,gt) = splitLookup kx t-    tl            = intersectWithKey f lt l-    tr            = intersectWithKey f gt r----{---------------------------------------------------------------------  Subset---------------------------------------------------------------------}--- | /O(n+m)/. --- This function is defined as (@subset = subsetBy (==)@).-subset :: (Ord k,Eq a) => Map k a -> Map k a -> Bool-subset m1 m2-  = subsetBy (==) m1 m2--{- | /O(n+m)/. - The expression (@subsetBy f t1 t2@) returns @True@ if- all keys in @t1@ are in tree @t2@, and when @f@ returns @True@ when- applied to their respective values. For example, the following - expressions are all @True@.- - > subsetBy (==) (fromList [('a',1)]) (fromList [('a',1),('b',2)])- > subsetBy (<=) (fromList [('a',1)]) (fromList [('a',1),('b',2)])- > subsetBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1),('b',2)])-- But the following are all @False@:- - > subsetBy (==) (fromList [('a',2)]) (fromList [('a',1),('b',2)])- > subsetBy (<)  (fromList [('a',1)]) (fromList [('a',1),('b',2)])- > subsetBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1)])--}-subsetBy :: Ord k => (a->a->Bool) -> Map k a -> Map k a -> Bool-subsetBy f t1 t2-  = (size t1 <= size t2) && (subset' f t1 t2)--subset' f Tip t = True-subset' f t Tip = False-subset' f (Bin _ kx x l r) t-  = case found of-      Nothing -> False-      Just y  -> f x y && subset' f l lt && subset' f r gt-  where-    (found,lt,gt) = splitLookup kx t---- | /O(n+m)/. Is this a proper subset? (ie. a subset but not equal). --- Defined as (@properSubset = properSubsetBy (==)@).-properSubset :: (Ord k,Eq a) => Map k a -> Map k a -> Bool-properSubset m1 m2-  = properSubsetBy (==) m1 m2--{- | /O(n+m)/. Is this a proper subset? (ie. a subset but not equal).- The expression (@properSubsetBy f m1 m2@) returns @True@ when- @m1@ and @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@.- -  > properSubsetBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])-  > properSubsetBy (<=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])-- But the following are all @False@:- -  > properSubsetBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])-  > properSubsetBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])-  > properSubsetBy (<)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])--}-properSubsetBy :: (Ord k,Eq a) => (a -> a -> Bool) -> Map k a -> Map k a -> Bool-properSubsetBy f t1 t2-  = (size t1 < size t2) && (subset' f t1 t2)--{---------------------------------------------------------------------  Filter and partition---------------------------------------------------------------------}--- | /O(n)/. Filter all values that satisfy the predicate.-filter :: Ord k => (a -> Bool) -> Map k a -> Map k a-filter p m-  = filterWithKey (\k x -> p x) m---- | /O(n)/. Filter all keys\values that satisfy the predicate.-filterWithKey :: Ord k => (k -> a -> Bool) -> Map k a -> Map k a-filterWithKey p Tip = Tip-filterWithKey p (Bin _ kx x l r)-  | p kx x    = join kx x (filterWithKey p l) (filterWithKey p r)-  | otherwise = merge (filterWithKey p l) (filterWithKey p r)----- | /O(n)/. partition the map according to a predicate. The first--- map contains all elements that satisfy the predicate, the second all--- elements that fail the predicate. See also 'split'.-partition :: Ord k => (a -> Bool) -> Map k a -> (Map k a,Map k a)-partition p m-  = partitionWithKey (\k x -> p x) m---- | /O(n)/. partition the map according to a predicate. The first--- map contains all elements that satisfy the predicate, the second all--- elements that fail the predicate. See also 'split'.-partitionWithKey :: Ord k => (k -> a -> Bool) -> Map k a -> (Map k a,Map k a)-partitionWithKey p Tip = (Tip,Tip)-partitionWithKey p (Bin _ kx x l r)-  | p kx x    = (join kx x l1 r1,merge l2 r2)-  | otherwise = (merge l1 r1,join kx x l2 r2)-  where-    (l1,l2) = partitionWithKey p l-    (r1,r2) = partitionWithKey p r---{---------------------------------------------------------------------  Mapping---------------------------------------------------------------------}--- | /O(n)/. Map a function over all values in the map.-map :: (a -> b) -> Map k a -> Map k b-map f m-  = mapWithKey (\k x -> f x) m---- | /O(n)/. Map a function over all values in the map.-mapWithKey :: (k -> a -> b) -> Map k a -> Map k b-mapWithKey f Tip = Tip-mapWithKey f (Bin sx kx x l r) -  = Bin sx kx (f kx x) (mapWithKey f l) (mapWithKey f r)---- | /O(n)/. The function @mapAccum@ threads an accumulating--- argument through the map in an unspecified order.-mapAccum :: (a -> b -> (a,c)) -> a -> Map k b -> (a,Map k c)-mapAccum f a m-  = mapAccumWithKey (\a k x -> f a x) a m---- | /O(n)/. The function @mapAccumWithKey@ threads an accumulating--- argument through the map in unspecified order. (= ascending pre-order)-mapAccumWithKey :: (a -> k -> b -> (a,c)) -> a -> Map k b -> (a,Map k c)-mapAccumWithKey f a t-  = mapAccumL f a t---- | /O(n)/. The function @mapAccumL@ threads an accumulating--- argument throught the map in (ascending) pre-order.-mapAccumL :: (a -> k -> b -> (a,c)) -> a -> Map k b -> (a,Map k c)-mapAccumL f a t-  = case t of-      Tip -> (a,Tip)-      Bin sx kx x l r-          -> let (a1,l') = mapAccumL f a l-                 (a2,x') = f a1 kx x-                 (a3,r') = mapAccumL f a2 r-             in (a3,Bin sx kx x' l' r')---- | /O(n)/. The function @mapAccumR@ threads an accumulating--- argument throught the map in (descending) post-order.-mapAccumR :: (a -> k -> b -> (a,c)) -> a -> Map k b -> (a,Map k c)-mapAccumR f a t-  = case t of-      Tip -> (a,Tip)-      Bin sx kx x l r -          -> let (a1,r') = mapAccumR f a r-                 (a2,x') = f a1 kx x-                 (a3,l') = mapAccumR f a2 l-             in (a3,Bin sx kx x' l' r')--{---------------------------------------------------------------------  Folds  ---------------------------------------------------------------------}--- | /O(n)/. Fold the map in an unspecified order. (= descending post-order).-fold :: (a -> b -> b) -> b -> Map k a -> b-fold f z m-  = foldWithKey (\k x z -> f x z) z m---- | /O(n)/. Fold the map in an unspecified order. (= descending post-order).-foldWithKey :: (k -> a -> b -> b) -> b -> Map k a -> b-foldWithKey f z t-  = foldR f z t---- | /O(n)/. In-order fold.-foldI :: (k -> a -> b -> b -> b) -> b -> Map k a -> b -foldI f z Tip               = z-foldI f z (Bin _ kx x l r)  = f kx x (foldI f z l) (foldI f z r)---- | /O(n)/. Post-order fold.-foldR :: (k -> a -> b -> b) -> b -> Map k a -> b-foldR f z Tip              = z-foldR f z (Bin _ kx x l r) = foldR f (f kx x (foldR f z r)) l---- | /O(n)/. Pre-order fold.-foldL :: (b -> k -> a -> b) -> b -> Map k a -> b-foldL f z Tip              = z-foldL f z (Bin _ kx x l r) = foldL f (f (foldL f z l) kx x) r--{---------------------------------------------------------------------  List variations ---------------------------------------------------------------------}--- | /O(n)/. Return all elements of the map.-elems :: Map k a -> [a]-elems m-  = [x | (k,x) <- assocs m]---- | /O(n)/. Return all keys of the map.-keys  :: Map k a -> [k]-keys m-  = [k | (k,x) <- assocs m]---- | /O(n)/. Return all key\/value pairs in the map.-assocs :: Map k a -> [(k,a)]-assocs m-  = toList m--{---------------------------------------------------------------------  Lists -  use [foldlStrict] to reduce demand on the control-stack---------------------------------------------------------------------}--- | /O(n*log n)/. Build a map from a list of key\/value pairs. See also 'fromAscList'.-fromList :: Ord k => [(k,a)] -> Map k a -fromList xs       -  = foldlStrict ins empty xs-  where-    ins t (k,x) = insert k x t---- | /O(n*log n)/. Build a map from a list of key\/value pairs with a combining function. See also 'fromAscListWith'.-fromListWith :: Ord k => (a -> a -> a) -> [(k,a)] -> Map k a -fromListWith f xs-  = fromListWithKey (\k x y -> f x y) xs---- | /O(n*log n)/. Build a map from a list of key\/value pairs with a combining function. See also 'fromAscListWithKey'.-fromListWithKey :: Ord k => (k -> a -> a -> a) -> [(k,a)] -> Map k a -fromListWithKey f xs -  = foldlStrict ins empty xs-  where-    ins t (k,x) = insertWithKey f k x t---- | /O(n)/. Convert to a list of key\/value pairs.-toList :: Map k a -> [(k,a)]-toList t      = toAscList t---- | /O(n)/. Convert to an ascending list.-toAscList :: Map k a -> [(k,a)]-toAscList t   = foldR (\k x xs -> (k,x):xs) [] t---- | /O(n)/. -toDescList :: Map k a -> [(k,a)]-toDescList t  = foldL (\xs k x -> (k,x):xs) [] t---{---------------------------------------------------------------------  Building trees from ascending/descending lists can be done in linear time.-  -  Note that if [xs] is ascending that: -    fromAscList xs       == fromList xs-    fromAscListWith f xs == fromListWith f xs---------------------------------------------------------------------}--- | /O(n)/. Build a map from an ascending list in linear time.-fromAscList :: Eq k => [(k,a)] -> Map k a -fromAscList xs-  = fromAscListWithKey (\k x y -> x) xs---- | /O(n)/. Build a map from an ascending list in linear time with a combining function for equal keys.-fromAscListWith :: Eq k => (a -> a -> a) -> [(k,a)] -> Map k a -fromAscListWith f xs-  = fromAscListWithKey (\k x y -> f x y) xs---- | /O(n)/. Build a map from an ascending list in linear time with a combining function for equal keys-fromAscListWithKey :: Eq k => (k -> a -> a -> a) -> [(k,a)] -> Map k a -fromAscListWithKey f xs-  = fromDistinctAscList (combineEq f xs)-  where-  -- [combineEq f xs] combines equal elements with function [f] in an ordered list [xs]-  combineEq f xs-    = case xs of-        []     -> []-        [x]    -> [x]-        (x:xx) -> combineEq' x xx--  combineEq' z [] = [z]-  combineEq' z@(kz,zz) (x@(kx,xx):xs)-    | kx==kz    = let yy = f kx xx zz in combineEq' (kx,yy) xs-    | otherwise = z:combineEq' x xs----- | /O(n)/. Build a map from an ascending list of distinct elements in linear time.-fromDistinctAscList :: [(k,a)] -> Map k a -fromDistinctAscList xs-  = build const (length xs) xs-  where-    -- 1) use continutations so that we use heap space instead of stack space.-    -- 2) special case for n==5 to build bushier trees. -    build c 0 xs   = c Tip xs -    build c 5 xs   = case xs of-                       ((k1,x1):(k2,x2):(k3,x3):(k4,x4):(k5,x5):xx) -                            -> c (bin k4 x4 (bin k2 x2 (single k1 x1) (single k3 x3)) (single k5 x5)) xx-    build c n xs   = seq nr $ build (buildR nr c) nl xs-                   where-                     nl = n `div` 2-                     nr = n - nl - 1--    buildR n c l ((k,x):ys) = build (buildB l k x c) n ys-    buildB l k x c r zs     = c (bin k x l r) zs-                      ---{---------------------------------------------------------------------  Utility functions that return sub-ranges of the original-  tree. Some functions take a comparison function as argument to-  allow comparisons against infinite values. A function [cmplo k]-  should be read as [compare lo k].--  [trim cmplo cmphi t]  A tree that is either empty or where [cmplo k == LT]-                        and [cmphi k == GT] for the key [k] of the root.-  [filterGt cmp t]      A tree where for all keys [k]. [cmp k == LT]-  [filterLt cmp t]      A tree where for all keys [k]. [cmp k == GT]--  [split k t]           Returns two trees [l] and [r] where all keys-                        in [l] are <[k] and all keys in [r] are >[k].-  [splitLookup k t]     Just like [split] but also returns whether [k]-                        was found in the tree.---------------------------------------------------------------------}--{---------------------------------------------------------------------  [trim lo hi t] trims away all subtrees that surely contain no-  values between the range [lo] to [hi]. The returned tree is either-  empty or the key of the root is between @lo@ and @hi@.---------------------------------------------------------------------}-trim :: (k -> Ordering) -> (k -> Ordering) -> Map k a -> Map k a-trim cmplo cmphi Tip = Tip-trim cmplo cmphi t@(Bin sx kx x l r)-  = case cmplo kx of-      LT -> case cmphi kx of-              GT -> t-              le -> trim cmplo cmphi l-      ge -> trim cmplo cmphi r-              -trimLookupLo :: Ord k => k -> (k -> Ordering) -> Map k a -> (Maybe a, Map k a)-trimLookupLo lo cmphi Tip = (Nothing,Tip)-trimLookupLo lo cmphi t@(Bin sx kx x l r)-  = case compare lo kx of-      LT -> case cmphi kx of-              GT -> (lookup lo t, t)-              le -> trimLookupLo lo cmphi l-      GT -> trimLookupLo lo cmphi r-      EQ -> (Just x,trim (compare lo) cmphi r)---{---------------------------------------------------------------------  [filterGt k t] filter all keys >[k] from tree [t]-  [filterLt k t] filter all keys <[k] from tree [t]---------------------------------------------------------------------}-filterGt :: Ord k => (k -> Ordering) -> Map k a -> Map k a-filterGt cmp Tip = Tip-filterGt cmp (Bin sx kx x l r)-  = case cmp kx of-      LT -> join kx x (filterGt cmp l) r-      GT -> filterGt cmp r-      EQ -> r-      -filterLt :: Ord k => (k -> Ordering) -> Map k a -> Map k a-filterLt cmp Tip = Tip-filterLt cmp (Bin sx kx x l r)-  = case cmp kx of-      LT -> filterLt cmp l-      GT -> join kx x l (filterLt cmp r)-      EQ -> l--{---------------------------------------------------------------------  Split---------------------------------------------------------------------}--- | /O(log n)/. The expression (@split k map@) is a pair @(map1,map2)@ where--- the keys in @map1@ are smaller than @k@ and the keys in @map2@ larger than @k@.-split :: Ord k => k -> Map k a -> (Map k a,Map k a)-split k Tip = (Tip,Tip)-split k (Bin sx kx x l r)-  = case compare k kx of-      LT -> let (lt,gt) = split k l in (lt,join kx x gt r)-      GT -> let (lt,gt) = split k r in (join kx x l lt,gt)-      EQ -> (l,r)---- | /O(log n)/. The expression (@splitLookup k map@) splits a map just--- like 'split' but also returns @lookup k map@.-splitLookup :: Ord k => k -> Map k a -> (Maybe a,Map k a,Map k a)-splitLookup k Tip = (Nothing,Tip,Tip)-splitLookup k (Bin sx kx x l r)-  = case compare k kx of-      LT -> let (z,lt,gt) = splitLookup k l in (z,lt,join kx x gt r)-      GT -> let (z,lt,gt) = splitLookup k r in (z,join kx x l lt,gt)-      EQ -> (Just x,l,r)--{---------------------------------------------------------------------  Utility functions that maintain the balance properties of the tree.-  All constructors assume that all values in [l] < [k] and all values-  in [r] > [k], and that [l] and [r] are valid trees.-  -  In order of sophistication:-    [Bin sz k x l r]  The type constructor.-    [bin k x l r]     Maintains the correct size, assumes that both [l]-                      and [r] are balanced with respect to each other.-    [balance k x l r] Restores the balance and size.-                      Assumes that the original tree was balanced and-                      that [l] or [r] has changed by at most one element.-    [join k x l r]    Restores balance and size. --  Furthermore, we can construct a new tree from two trees. Both operations-  assume that all values in [l] < all values in [r] and that [l] and [r]-  are valid:-    [glue l r]        Glues [l] and [r] together. Assumes that [l] and-                      [r] are already balanced with respect to each other.-    [merge l r]       Merges two trees and restores balance.--  Note: in contrast to Adam's paper, we use (<=) comparisons instead-  of (<) comparisons in [join], [merge] and [balance]. -  Quickcheck (on [difference]) showed that this was necessary in order -  to maintain the invariants. It is quite unsatisfactory that I haven't -  been able to find out why this is actually the case! Fortunately, it -  doesn't hurt to be a bit more conservative.---------------------------------------------------------------------}--{---------------------------------------------------------------------  Join ---------------------------------------------------------------------}-join :: Ord k => k -> a -> Map k a -> Map k a -> Map k a-join kx x Tip r  = insertMin kx x r-join kx x l Tip  = insertMax kx x l-join kx x l@(Bin sizeL ky y ly ry) r@(Bin sizeR kz z lz rz)-  | delta*sizeL <= sizeR  = balance kz z (join kx x l lz) rz-  | delta*sizeR <= sizeL  = balance ky y ly (join kx x ry r)-  | otherwise             = bin kx x l r----- insertMin and insertMax don't perform potentially expensive comparisons.-insertMax,insertMin :: k -> a -> Map k a -> Map k a -insertMax kx x t-  = case t of-      Tip -> single kx x-      Bin sz ky y l r-          -> balance ky y l (insertMax kx x r)-             -insertMin kx x t-  = case t of-      Tip -> single kx x-      Bin sz ky y l r-          -> balance ky y (insertMin kx x l) r-             -{---------------------------------------------------------------------  [merge l r]: merges two trees.---------------------------------------------------------------------}-merge :: Map k a -> Map k a -> Map k a-merge Tip r   = r-merge l Tip   = l-merge l@(Bin sizeL kx x lx rx) r@(Bin sizeR ky y ly ry)-  | delta*sizeL <= sizeR = balance ky y (merge l ly) ry-  | delta*sizeR <= sizeL = balance kx x lx (merge rx r)-  | otherwise            = glue l r--{---------------------------------------------------------------------  [glue l r]: glues two trees together.-  Assumes that [l] and [r] are already balanced with respect to each other.---------------------------------------------------------------------}-glue :: Map k a -> Map k a -> Map k a-glue Tip r = r-glue l Tip = l-glue l r   -  | size l > size r = let ((km,m),l') = deleteFindMax l in balance km m l' r-  | otherwise       = let ((km,m),r') = deleteFindMin r in balance km m l r'----- | /O(log n)/. Delete and find the minimal element.-deleteFindMin :: Map k a -> ((k,a),Map k a)-deleteFindMin t -  = case t of-      Bin _ k x Tip r -> ((k,x),r)-      Bin _ k x l r   -> let (km,l') = deleteFindMin l in (km,balance k x l' r)-      Tip             -> (error "Map.deleteFindMin: can not return the minimal element of an empty map", Tip)---- | /O(log n)/. Delete and find the maximal element.-deleteFindMax :: Map k a -> ((k,a),Map k a)-deleteFindMax t-  = case t of-      Bin _ k x l Tip -> ((k,x),l)-      Bin _ k x l r   -> let (km,r') = deleteFindMax r in (km,balance k x l r')-      Tip             -> (error "Map.deleteFindMax: can not return the maximal element of an empty map", Tip)---{---------------------------------------------------------------------  [balance l x r] balances two trees with value x.-  The sizes of the trees should balance after decreasing the-  size of one of them. (a rotation).--  [delta] is the maximal relative difference between the sizes of-          two trees, it corresponds with the [w] in Adams' paper.-  [ratio] is the ratio between an outer and inner sibling of the-          heavier subtree in an unbalanced setting. It determines-          whether a double or single rotation should be performed-          to restore balance. It is correspondes with the inverse-          of $\alpha$ in Adam's article.--  Note that:-  - [delta] should be larger than 4.646 with a [ratio] of 2.-  - [delta] should be larger than 3.745 with a [ratio] of 1.534.-  -  - A lower [delta] leads to a more 'perfectly' balanced tree.-  - A higher [delta] performs less rebalancing.--  - Balancing is automaic for random data and a balancing-    scheme is only necessary to avoid pathological worst cases.-    Almost any choice will do, and in practice, a rather large-    [delta] may perform better than smaller one.--  Note: in contrast to Adam's paper, we use a ratio of (at least) [2]-  to decide whether a single or double rotation is needed. Allthough-  he actually proves that this ratio is needed to maintain the-  invariants, his implementation uses an invalid ratio of [1].---------------------------------------------------------------------}-delta,ratio :: Int-delta = 5-ratio = 2--balance :: k -> a -> Map k a -> Map k a -> Map k a-balance k x l r-  | sizeL + sizeR <= 1    = Bin sizeX k x l r-  | sizeR >= delta*sizeL  = rotateL k x l r-  | sizeL >= delta*sizeR  = rotateR k x l r-  | otherwise             = Bin sizeX k x l r-  where-    sizeL = size l-    sizeR = size r-    sizeX = sizeL + sizeR + 1---- rotate-rotateL k x l r@(Bin _ _ _ ly ry)-  | size ly < ratio*size ry = singleL k x l r-  | otherwise               = doubleL k x l r--rotateR k x l@(Bin _ _ _ ly ry) r-  | size ry < ratio*size ly = singleR k x l r-  | otherwise               = doubleR k x l r---- basic rotations-singleL k1 x1 t1 (Bin _ k2 x2 t2 t3)  = bin k2 x2 (bin k1 x1 t1 t2) t3-singleR k1 x1 (Bin _ k2 x2 t1 t2) t3  = bin k2 x2 t1 (bin k1 x1 t2 t3)--doubleL k1 x1 t1 (Bin _ k2 x2 (Bin _ k3 x3 t2 t3) t4) = bin k3 x3 (bin k1 x1 t1 t2) (bin k2 x2 t3 t4)-doubleR k1 x1 (Bin _ k2 x2 t1 (Bin _ k3 x3 t2 t3)) t4 = bin k3 x3 (bin k2 x2 t1 t2) (bin k1 x1 t3 t4)---{---------------------------------------------------------------------  The bin constructor maintains the size of the tree---------------------------------------------------------------------}-bin :: k -> a -> Map k a -> Map k a -> Map k a-bin k x l r-  = Bin (size l + size r + 1) k x l r---{---------------------------------------------------------------------  Eq converts the tree to a list. In a lazy setting, this -  actually seems one of the faster methods to compare two trees -  and it is certainly the simplest :-)---------------------------------------------------------------------}-instance (Eq k,Eq a) => Eq (Map k a) where-  t1 == t2  = (size t1 == size t2) && (toAscList t1 == toAscList t2)--{---------------------------------------------------------------------  Functor---------------------------------------------------------------------}-instance Functor (Map k) where-  fmap f m  = map f m--{---------------------------------------------------------------------  Show---------------------------------------------------------------------}-instance (Show k, Show a) => Show (Map k a) where-  showsPrec d m  = showMap (toAscList m)--showMap :: (Show k,Show a) => [(k,a)] -> ShowS-showMap []     -  = showString "{}" -showMap (x:xs) -  = showChar '{' . showElem x . showTail xs-  where-    showTail []     = showChar '}'-    showTail (x:xs) = showChar ',' . showElem x . showTail xs-    -    showElem (k,x)  = shows k . showString ":=" . shows x-  ---- | /O(n)/. Show the tree that implements the map. The tree is shown--- in a compressed, hanging format.-showTree :: (Show k,Show a) => Map k a -> String-showTree m-  = showTreeWith showElem True False m-  where-    showElem k x  = show k ++ ":=" ++ show x---{- | /O(n)/. The expression (@showTreeWith showelem hang wide map@) shows- the tree that implements the map. Elements are shown using the @showElem@ function. 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.-->  Map> putStrLn $ showTreeWith (\k x -> show (k,x)) True False $ fromDistinctAscList [(x,()) | x <- [1..5]]->  (4,())->  +--(2,())->  |  +--(1,())->  |  +--(3,())->  +--(5,())->->  Map> putStrLn $ showTreeWith (\k x -> show (k,x)) True True $ fromDistinctAscList [(x,()) | x <- [1..5]]->  (4,())->  |->  +--(2,())->  |  |->  |  +--(1,())->  |  |->  |  +--(3,())->  |->  +--(5,())->->  Map> putStrLn $ showTreeWith (\k x -> show (k,x)) False True $ fromDistinctAscList [(x,()) | x <- [1..5]]->  +--(5,())->  |->  (4,())->  |->  |  +--(3,())->  |  |->  +--(2,())->     |->     +--(1,())---}-showTreeWith :: (k -> a -> String) -> Bool -> Bool -> Map k a -> String-showTreeWith showelem hang wide t-  | hang      = (showsTreeHang showelem wide [] t) ""-  | otherwise = (showsTree showelem wide [] [] t) ""--showsTree :: (k -> a -> String) -> Bool -> [String] -> [String] -> Map k a -> ShowS-showsTree showelem wide lbars rbars t-  = case t of-      Tip -> showsBars lbars . showString "|\n"-      Bin sz kx x Tip Tip-          -> showsBars lbars . showString (showelem kx x) . showString "\n" -      Bin sz kx x l r-          -> showsTree showelem wide (withBar rbars) (withEmpty rbars) r .-             showWide wide rbars .-             showsBars lbars . showString (showelem kx x) . showString "\n" .-             showWide wide lbars .-             showsTree showelem wide (withEmpty lbars) (withBar lbars) l--showsTreeHang :: (k -> a -> String) -> Bool -> [String] -> Map k a -> ShowS-showsTreeHang showelem wide bars t-  = case t of-      Tip -> showsBars bars . showString "|\n" -      Bin sz kx x Tip Tip-          -> showsBars bars . showString (showelem kx x) . showString "\n" -      Bin sz kx x l r-          -> showsBars bars . showString (showelem kx x) . showString "\n" . -             showWide wide bars .-             showsTreeHang showelem wide (withBar bars) l .-             showWide wide bars .-             showsTreeHang showelem wide (withEmpty bars) r---showWide wide bars -  | wide      = showString (concat (reverse bars)) . showString "|\n" -  | otherwise = id--showsBars :: [String] -> ShowS-showsBars bars-  = case bars of-      [] -> id-      _  -> showString (concat (reverse (tail bars))) . showString node--node           = "+--"-withBar bars   = "|  ":bars-withEmpty bars = "   ":bars---{---------------------------------------------------------------------  Assertions---------------------------------------------------------------------}--- | /O(n)/. Test if the internal map structure is valid.-valid :: Ord k => Map k a -> Bool-valid t-  = balanced t && ordered t && validsize t--ordered t-  = bounded (const True) (const True) t-  where-    bounded lo hi t-      = case t of-          Tip              -> True-          Bin sz kx x l r  -> (lo kx) && (hi kx) && bounded lo (<kx) l && bounded (>kx) hi r---- | Exported only for "Debug.QuickCheck"-balanced :: Map k a -> Bool-balanced t-  = case t of-      Tip              -> True-      Bin sz kx x l r  -> (size l + size r <= 1 || (size l <= delta*size r && size r <= delta*size l)) &&-                          balanced l && balanced r---validsize t-  = (realsize t == Just (size t))-  where-    realsize t-      = case t of-          Tip             -> Just 0-          Bin sz kx x l r -> case (realsize l,realsize r) of-                              (Just n,Just m)  | n+m+1 == sz  -> Just sz-                              other            -> Nothing--{---------------------------------------------------------------------  Utilities---------------------------------------------------------------------}-foldlStrict f z xs-  = case xs of-      []     -> z-      (x:xx) -> let z' = f z x in seq z' (foldlStrict f z' xx)---{--{---------------------------------------------------------------------  Testing---------------------------------------------------------------------}-testTree xs   = fromList [(x,"*") | x <- xs]-test1 = testTree [1..20]-test2 = testTree [30,29..10]-test3 = testTree [1,4,6,89,2323,53,43,234,5,79,12,9,24,9,8,423,8,42,4,8,9,3]--{---------------------------------------------------------------------  QuickCheck---------------------------------------------------------------------}-qcheck prop-  = check config prop-  where-    config = Config-      { configMaxTest = 500-      , configMaxFail = 5000-      , configSize    = \n -> (div n 2 + 3)-      , configEvery   = \n args -> let s = show n in s ++ [ '\b' | _ <- s ]-      }---{---------------------------------------------------------------------  Arbitrary, reasonably balanced trees---------------------------------------------------------------------}-instance (Enum k,Arbitrary a) => Arbitrary (Map k a) where-  arbitrary = sized (arbtree 0 maxkey)-            where maxkey  = 10000--arbtree :: (Enum k,Arbitrary a) => Int -> Int -> Int -> Gen (Map k a)-arbtree lo hi n-  | n <= 0        = return Tip-  | lo >= hi      = return Tip-  | otherwise     = do{ x  <- arbitrary -                      ; i  <- choose (lo,hi)-                      ; m  <- choose (1,30)-                      ; let (ml,mr)  | m==(1::Int)= (1,2)-                                     | m==2       = (2,1)-                                     | m==3       = (1,1)-                                     | otherwise  = (2,2)-                      ; l  <- arbtree lo (i-1) (n `div` ml)-                      ; r  <- arbtree (i+1) hi (n `div` mr)-                      ; return (bin (toEnum i) x l r)-                      }  ---{---------------------------------------------------------------------  Valid tree's---------------------------------------------------------------------}-forValid :: (Show k,Enum k,Show a,Arbitrary a,Testable b) => (Map k a -> b) -> Property-forValid f-  = forAll arbitrary $ \t -> ---    classify (balanced t) "balanced" $-    classify (size t == 0) "empty" $-    classify (size t > 0  && size t <= 10) "small" $-    classify (size t > 10 && size t <= 64) "medium" $-    classify (size t > 64) "large" $-    balanced t ==> f t--forValidIntTree :: Testable a => (Map Int Int -> a) -> Property-forValidIntTree f-  = forValid f--forValidUnitTree :: Testable a => (Map Int () -> a) -> Property-forValidUnitTree f-  = forValid f---prop_Valid -  = forValidUnitTree $ \t -> valid t--{---------------------------------------------------------------------  Single, Insert, Delete---------------------------------------------------------------------}-prop_Single :: Int -> Int -> Bool-prop_Single k x-  = (insert k x empty == single k x)--prop_InsertValid :: Int -> Property-prop_InsertValid k-  = forValidUnitTree $ \t -> valid (insert k () t)--prop_InsertDelete :: Int -> Map Int () -> Property-prop_InsertDelete k t-  = (lookup k t == Nothing) ==> delete k (insert k () t) == t--prop_DeleteValid :: Int -> Property-prop_DeleteValid k-  = forValidUnitTree $ \t -> -    valid (delete k (insert k () t))--{---------------------------------------------------------------------  Balance---------------------------------------------------------------------}-prop_Join :: Int -> Property -prop_Join k -  = forValidUnitTree $ \t ->-    let (l,r) = split k t-    in valid (join k () l r)--prop_Merge :: Int -> Property -prop_Merge k-  = forValidUnitTree $ \t ->-    let (l,r) = split k t-    in valid (merge l r)---{---------------------------------------------------------------------  Union---------------------------------------------------------------------}-prop_UnionValid :: Property-prop_UnionValid-  = forValidUnitTree $ \t1 ->-    forValidUnitTree $ \t2 ->-    valid (union t1 t2)--prop_UnionInsert :: Int -> Int -> Map Int Int -> Bool-prop_UnionInsert k x t-  = union (single k x) t == insert k x t--prop_UnionAssoc :: Map Int Int -> Map Int Int -> Map Int Int -> Bool-prop_UnionAssoc t1 t2 t3-  = union t1 (union t2 t3) == union (union t1 t2) t3--prop_UnionComm :: Map Int Int -> Map Int Int -> Bool-prop_UnionComm t1 t2-  = (union t1 t2 == unionWith (\x y -> y) t2 t1)--prop_UnionWithValid -  = forValidIntTree $ \t1 ->-    forValidIntTree $ \t2 ->-    valid (unionWithKey (\k x y -> x+y) t1 t2)--prop_UnionWith :: [(Int,Int)] -> [(Int,Int)] -> Bool-prop_UnionWith xs ys-  = sum (elems (unionWith (+) (fromListWith (+) xs) (fromListWith (+) ys))) -    == (sum (Prelude.map snd xs) + sum (Prelude.map snd ys))--prop_DiffValid-  = forValidUnitTree $ \t1 ->-    forValidUnitTree $ \t2 ->-    valid (difference t1 t2)--prop_Diff :: [(Int,Int)] -> [(Int,Int)] -> Bool-prop_Diff xs ys-  =  List.sort (keys (difference (fromListWith (+) xs) (fromListWith (+) ys))) -    == List.sort ((List.\\) (nub (Prelude.map fst xs))  (nub (Prelude.map fst ys)))--prop_IntValid-  = forValidUnitTree $ \t1 ->-    forValidUnitTree $ \t2 ->-    valid (intersection t1 t2)--prop_Int :: [(Int,Int)] -> [(Int,Int)] -> Bool-prop_Int xs ys-  =  List.sort (keys (intersection (fromListWith (+) xs) (fromListWith (+) ys))) -    == List.sort (nub ((List.intersect) (Prelude.map fst xs)  (Prelude.map fst ys)))--{---------------------------------------------------------------------  Lists---------------------------------------------------------------------}-prop_Ordered-  = forAll (choose (5,100)) $ \n ->-    let xs = [(x,()) | x <- [0..n::Int]] -    in fromAscList xs == fromList xs--prop_List :: [Int] -> Bool-prop_List xs-  = (sort (nub xs) == [x | (x,()) <- toList (fromList [(x,()) | x <- xs])])--}
− src/UU/DData/MultiSet.hs
@@ -1,430 +0,0 @@----------------------------------------------------------------------------------{-| Module      :  MultiSet-    Copyright   :  (c) Daan Leijen 2002-    License     :  BSD-style--    Maintainer  :  daan@cs.uu.nl-    Stability   :  provisional-    Portability :  portable--  An implementation of multi sets on top of the "Map" module. A multi set-  differs from a /bag/ in the sense that it is represented as a map from elements-  to occurrence counts instead of retaining all elements. This means that equality -  on elements should be defined as a /structural/ equality instead of an -  equivalence relation.   If this is not the  case, operations that observe the -  elements, like 'filter' and 'fold',  should be used with care.--}----------------------------------------------------------------------------------}-module UU.DData.MultiSet ( -            -- * MultiSet type-              MultiSet          -- instance Eq,Show-            -            -- * Operators-            , (\\)--            -- *Query-            , isEmpty-            , size-            , distinctSize-            , member-            , occur--            , subset-            , properSubset-            -            -- * Construction-            , empty-            , single-            , insert-            , insertMany-            , delete-            , deleteAll-            -            -- * Combine-            , union-            , difference-            , intersection-            , unions-            -            -- * Filter-            , filter-            , partition--            -- * Fold-            , fold-            , foldOccur--            -- * Min\/Max-            , findMin-            , findMax-            , deleteMin-            , deleteMax-            , deleteMinAll-            , deleteMaxAll-            -            -- * Conversion-            , elems--            -- ** List-            , toList-            , fromList--            -- ** Ordered list-            , toAscList-            , fromAscList-            , fromDistinctAscList--            -- ** Occurrence lists-            , toOccurList-            , toAscOccurList-            , fromOccurList-            , fromAscOccurList--            -- ** Map-            , toMap-            , fromMap-            , fromOccurMap-            -            -- * Debugging-            , showTree-            , showTreeWith-            , valid-            ) where--import Prelude   hiding  (map,filter)-import qualified Prelude (map,filter)--import qualified UU.DData.Map as M--{---------------------------------------------------------------------  Operators---------------------------------------------------------------------}-infixl 9 \\ ------ | /O(n+m)/. See 'difference'.-(\\) :: Ord a => MultiSet a -> MultiSet a -> MultiSet a-b1 \\ b2 = difference b1 b2--{---------------------------------------------------------------------  MultiSets are a simple wrapper around Maps, 'Map.Map'---------------------------------------------------------------------}--- | A multi set of values @a@.-newtype MultiSet a  = MultiSet (M.Map a Int)--{---------------------------------------------------------------------  Query---------------------------------------------------------------------}--- | /O(1)/. Is the multi set empty?-isEmpty :: MultiSet a -> Bool-isEmpty (MultiSet m)  -  = M.isEmpty m---- | /O(1)/. Returns the number of distinct elements in the multi set, ie. (@distinctSize mset == Set.size ('toSet' mset)@).-distinctSize :: MultiSet a -> Int-distinctSize (MultiSet m)     -  = M.size m---- | /O(n)/. The number of elements in the multi set.-size :: MultiSet a -> Int-size b-  = foldOccur (\x n m -> n+m) 0 b---- | /O(log n)/. Is the element in the multi set?-member :: Ord a => a -> MultiSet a -> Bool-member x m-  = (occur x m > 0)---- | /O(log n)/. The number of occurrences of an element in the multi set.-occur :: Ord a => a -> MultiSet a -> Int-occur x (MultiSet m)-  = case M.lookup x m of-      Nothing -> 0-      Just n  -> n---- | /O(n+m)/. Is this a subset of the multi set? -subset :: Ord a => MultiSet a -> MultiSet a -> Bool-subset (MultiSet m1) (MultiSet m2)-  = M.subsetBy (<=) m1 m2---- | /O(n+m)/. Is this a proper subset? (ie. a subset and not equal)-properSubset :: Ord a => MultiSet a -> MultiSet a -> Bool-properSubset b1 b2-  | distinctSize b1 == distinctSize b2 = (subset b1 b2) && (b1 /= b2)-  | distinctSize b1 <  distinctSize b2 = (subset b1 b2)-  | otherwise                      = False--{---------------------------------------------------------------------  Construction---------------------------------------------------------------------}--- | /O(1)/. Create an empty multi set.-empty :: MultiSet a-empty-  = MultiSet (M.empty)---- | /O(1)/. Create a singleton multi set.-single :: a -> MultiSet a-single x -  = MultiSet (M.single x 1)-    -{---------------------------------------------------------------------  Insertion, Deletion---------------------------------------------------------------------}--- | /O(log n)/. Insert an element in the multi set.-insert :: Ord a => a -> MultiSet a -> MultiSet a-insert x (MultiSet m)          -  = MultiSet (M.insertWith (+) x 1 m)---- | /O(min(n,W))/. The expression (@insertMany x count mset@)--- inserts @count@ instances of @x@ in the multi set @mset@.-insertMany ::  Ord a => a -> Int -> MultiSet a -> MultiSet a--- We still expect not to get count < 0-insertMany x 0 multiset = multiset-insertMany x count (MultiSet m)          -  = MultiSet (M.insertWith (+) x count m)---- | /O(log n)/. Delete a single element.-delete :: Ord a => a -> MultiSet a -> MultiSet a-delete x (MultiSet m)-  = MultiSet (M.updateWithKey f x m)-  where-    f x n  | n > 1     = Just (n-1)-           | otherwise = Nothing---- | /O(log n)/. Delete all occurrences of an element.-deleteAll :: Ord a => a -> MultiSet a -> MultiSet a-deleteAll x (MultiSet m)-  = MultiSet (M.delete x m)--{---------------------------------------------------------------------  Combine---------------------------------------------------------------------}--- | /O(n+m)/. Union of two multisets. The union adds the elements together.------ > MultiSet\> union (fromList [1,1,2]) (fromList [1,2,2,3])--- > {1,1,1,2,2,2,3}-union :: Ord a => MultiSet a -> MultiSet a -> MultiSet a-union (MultiSet t1) (MultiSet t2)-  = MultiSet (M.unionWith (+) t1 t2)---- | /O(n+m)/. Intersection of two multisets.------ > MultiSet\> intersection (fromList [1,1,2]) (fromList [1,2,2,3])--- > {1,2}-intersection :: Ord a => MultiSet a -> MultiSet a -> MultiSet a-intersection (MultiSet t1) (MultiSet t2)-  = MultiSet (M.intersectionWith min t1 t2)---- | /O(n+m)/. Difference between two multisets.------ > MultiSet\> difference (fromList [1,1,2]) (fromList [1,2,2,3])--- > {1}-difference   :: Ord a => MultiSet a -> MultiSet a -> MultiSet a-difference (MultiSet t1) (MultiSet t2)-  = MultiSet (M.differenceWithKey f t1 t2)-  where-    f x n m  | n-m > 0   = Just (n-m)-             | otherwise = Nothing---- | The union of a list of multisets.-unions :: Ord a => [MultiSet a] -> MultiSet a-unions multisets-  -- Original, wrong-  -- = MultiSet (M.unions [m | MultiSet m <- multisets])-  -- Map has no unionsWith-  -- = MultiSet (M.unionsWith (+) [m | MultiSet m <- multisets])-  -- Correct, but requires Data.List.foldl'-  -- = MultiSet (foldl' (M.unionWith (+)) M.empty [m | MultiSet m <- multisets])-  -- Correct, but not strict like the original (M.unions uses foldStrict)-  = foldr union empty multisets--{---------------------------------------------------------------------  Filter and partition---------------------------------------------------------------------}--- | /O(n)/. Filter all elements that satisfy some predicate.-filter :: Ord a => (a -> Bool) -> MultiSet a -> MultiSet a-filter p (MultiSet m)-  = MultiSet (M.filterWithKey (\x n -> p x) m)---- | /O(n)/. Partition the multi set according to some predicate.-partition :: Ord a => (a -> Bool) -> MultiSet a -> (MultiSet a,MultiSet a)-partition p (MultiSet m)-  = (MultiSet l,MultiSet r)-  where-    (l,r) = M.partitionWithKey (\x n -> p x) m--{---------------------------------------------------------------------  Fold---------------------------------------------------------------------}--- | /O(n)/. Fold over each element in the multi set.-fold :: (a -> b -> b) -> b -> MultiSet a -> b-fold f z (MultiSet m)-  = M.foldWithKey apply z m-  where-    apply x n z  | n > 0     = apply x (n-1) (f x z)-                 | otherwise = z---- | /O(n)/. Fold over all occurrences of an element at once.-foldOccur :: (a -> Int -> b -> b) -> b -> MultiSet a -> b-foldOccur f z (MultiSet m)-  = M.foldWithKey f z m--{---------------------------------------------------------------------  Minimal, Maximal---------------------------------------------------------------------}--- | /O(log n)/. The minimal element of a multi set.-findMin :: MultiSet a -> a-findMin (MultiSet m)-  = fst (M.findMin m)---- | /O(log n)/. The maximal element of a multi set.-findMax :: MultiSet a -> a-findMax (MultiSet m)-  = fst (M.findMax m)---- | /O(log n)/. Delete the minimal element.-deleteMin :: MultiSet a -> MultiSet a-deleteMin (MultiSet m)-  = MultiSet (M.updateMin f m)-  where-    f n  | n > 0     = Just (n-1)-         | otherwise = Nothing---- | /O(log n)/. Delete the maximal element.-deleteMax :: MultiSet a -> MultiSet a-deleteMax (MultiSet m)-  = MultiSet (M.updateMax f m)-  where-    f n  | n > 0     = Just (n-1)-         | otherwise = Nothing---- | /O(log n)/. Delete all occurrences of the minimal element.-deleteMinAll :: MultiSet a -> MultiSet a-deleteMinAll (MultiSet m)-  = MultiSet (M.deleteMin m)---- | /O(log n)/. Delete all occurrences of the maximal element.-deleteMaxAll :: MultiSet a -> MultiSet a-deleteMaxAll (MultiSet m)-  = MultiSet (M.deleteMax m)---{---------------------------------------------------------------------  List variations ---------------------------------------------------------------------}--- | /O(n)/. The list of elements.-elems :: MultiSet a -> [a]-elems s-  = toList s--{---------------------------------------------------------------------  Lists ---------------------------------------------------------------------}--- | /O(n)/. Create a list with all elements.-toList :: MultiSet a -> [a]-toList s-  = toAscList s---- | /O(n)/. Create an ascending list of all elements.-toAscList :: MultiSet a -> [a]-toAscList (MultiSet m)-  = [y | (x,n) <- M.toAscList m, y <- replicate n x]----- | /O(n*log n)/. Create a multi set from a list of elements.-fromList :: Ord a => [a] -> MultiSet a -fromList xs-  = MultiSet (M.fromListWith (+) [(x,1) | x <- xs])---- | /O(n)/. Create a multi set from an ascending list in linear time.-fromAscList :: Eq a => [a] -> MultiSet a -fromAscList xs-  = MultiSet (M.fromAscListWith (+) [(x,1) | x <- xs])---- | /O(n)/. Create a multi set from an ascending list of distinct elements in linear time.-fromDistinctAscList :: [a] -> MultiSet a -fromDistinctAscList xs-  = MultiSet (M.fromDistinctAscList [(x,1) | x <- xs])---- | /O(n)/. Create a list of element\/occurrence pairs.-toOccurList :: MultiSet a -> [(a,Int)]-toOccurList b-  = toAscOccurList b---- | /O(n)/. Create an ascending list of element\/occurrence pairs.-toAscOccurList :: MultiSet a -> [(a,Int)]-toAscOccurList (MultiSet m)-  = M.toAscList m---- | /O(n*log n)/. Create a multi set from a list of element\/occurrence pairs.-fromOccurList :: Ord a => [(a,Int)] -> MultiSet a-fromOccurList xs-  = MultiSet (M.fromListWith (+) (Prelude.filter (\(x,i) -> i > 0) xs))---- | /O(n)/. Create a multi set from an ascending list of element\/occurrence pairs.-fromAscOccurList :: Ord a => [(a,Int)] -> MultiSet a-fromAscOccurList xs-  = MultiSet (M.fromAscListWith (+) (Prelude.filter (\(x,i) -> i > 0) xs))--{---------------------------------------------------------------------  Maps---------------------------------------------------------------------}--- | /O(1)/. Convert to a 'Map.Map' from elements to number of occurrences.-toMap   :: MultiSet a -> M.Map a Int-toMap (MultiSet m)-  = m---- | /O(n)/. Convert a 'Map.Map' from elements to occurrences into a multi set.-fromMap :: Ord a => M.Map a Int -> MultiSet a-fromMap m-  = MultiSet (M.filter (>0) m)---- | /O(1)/. Convert a 'Map.Map' from elements to occurrences into a multi set.--- Assumes that the 'Map.Map' contains only elements that occur at least once.-fromOccurMap :: M.Map a Int -> MultiSet a-fromOccurMap m-  = MultiSet m--{---------------------------------------------------------------------  Eq, Ord---------------------------------------------------------------------}-instance Eq a => Eq (MultiSet a) where-  (MultiSet m1) == (MultiSet m2)  = (m1==m2) --{---------------------------------------------------------------------  Show---------------------------------------------------------------------}-instance Show a => Show (MultiSet a) where-  showsPrec d b  = showSet (toAscList b)--showSet :: Show a => [a] -> ShowS-showSet []     -  = showString "{}" -showSet (x:xs) -  = showChar '{' . shows x . showTail xs-  where-    showTail []     = showChar '}'-    showTail (x:xs) = showChar ',' . shows x . showTail xs-    --{---------------------------------------------------------------------  Debugging---------------------------------------------------------------------}--- | /O(n)/. Show the tree structure that implements the 'MultiSet'. The tree--- is shown as a compressed and /hanging/.-showTree :: (Show a) => MultiSet a -> String-showTree mset-  = showTreeWith True False mset---- | /O(n)/. The expression (@showTreeWith hang wide map@) shows--- the tree that implements the multi set. The tree is shown /hanging/ when @hang@ is @True@ --- and otherwise as a /rotated/ tree. When @wide@ is @True@ an extra wide version--- is shown.-showTreeWith :: Show a => Bool -> Bool -> MultiSet a -> String-showTreeWith hang wide (MultiSet m)-  = M.showTreeWith (\x n -> show x ++ " (" ++ show n ++ ")") hang wide m----- | /O(n)/. Is this a valid multi set?-valid :: Ord a => MultiSet a -> Bool-valid (MultiSet m)-  = M.valid m && (M.isEmpty (M.filter (<=0) m))
− src/UU/DData/Queue.hs
@@ -1,281 +0,0 @@----------------------------------------------------------------------------------{-| Module      :  Queue-    Copyright   :  (c) Daan Leijen 2002-    License     :  BSD-style--    Maintainer  :  daan@cs.uu.nl-    Stability   :  provisional-    Portability :  portable--  An efficient implementation of queues (FIFO buffers). Based on:--  * Chris Okasaki, \"/Simple and Efficient Purely Functional Queues and Deques/\",-    Journal of Functional Programming 5(4):583-592, October 1995.--}----------------------------------------------------------------------------------}-module UU.DData.Queue ( -            -- * Queue type-              Queue          -- instance Eq,Show--            -- * Operators-            , (<>)-            -            -- * Query-            , isEmpty-            , length-            , head-            , tail-            , front--            -- * Construction-            , empty-            , single-            , insert-            , append-            -            -- * Filter-            , filter-            , partition--            -- * Fold-            , foldL-            , foldR-           -            -- * Conversion-            , elems--            -- ** List-            , toList-            , fromList-            ) where--import qualified Prelude as P (length,filter)-import Prelude   hiding       (length,head,tail,filter)-import qualified List---- just for testing--- import QuickCheck --{---------------------------------------------------------------------  Operators---------------------------------------------------------------------}-infixr 5 <>---- | /O(n)/. Append two queues, see 'append'.-(<>) :: Queue a -> Queue a -> Queue a-s <> t-  = append s t--{---------------------------------------------------------------------  Queue.-  Invariants for @(Queue xs ys zs)@:-  * @length ys <= length xs@-  * @length zs == length xs - length ys@---------------------------------------------------------------------}--- A queue of elements @a@.-data Queue a  = Queue [a] [a] [a]--{---------------------------------------------------------------------  Query---------------------------------------------------------------------}---- | /O(1)/. Is the queue empty?-isEmpty :: Queue a -> Bool-isEmpty (Queue xs ys zs)-  = null xs---- | /O(n)/. The number of elements in the queue.-length :: Queue a -> Int-length (Queue xs ys zs)-  = P.length xs + P.length ys---- | /O(1)/. The element in front of the queue. Raises an error--- when the queue is empty.-head :: Queue a -> a-head (Queue xs ys zs)-  = case xs of-      (x:xx)  -> x-      []      -> error "Queue.head: empty queue"---- | /O(1)/. The tail of the queue.--- Raises an error when the queue is empty.-tail :: Queue a -> Queue a-tail (Queue xs ys zs)-  = case xs of-      (x:xx)  -> queue xx ys zs-      []      -> error "Queue.tail: empty queue"---- | /O(1)/. The head and tail of the queue.-front :: Queue a -> Maybe (a,Queue a)-front (Queue xs ys zs)-  = case xs of-      (x:xx)  -> Just (x,queue xx ys zs)-      []      -> Nothing---{---------------------------------------------------------------------  Construction  ---------------------------------------------------------------------}--- | /O(1)/. The empty queue.-empty :: Queue a-empty -  = Queue [] [] []---- | /O(1)/. A queue of one element.-single :: a -> Queue a-single x-  = Queue [x] [] [x]---- | /O(1)/. Insert an element at the back of a queue.-insert :: a -> Queue a -> Queue a-insert x (Queue xs ys zs)-  = queue xs (x:ys) zs----- | /O(n)/. Append two queues.-append :: Queue a -> Queue a -> Queue a-append (Queue xs1 ys1 zs1) (Queue xs2 ys2 zs2)-  = Queue (xs1++xs2) (ys1++ys2) (zs1++zs2)--{---------------------------------------------------------------------  Filter---------------------------------------------------------------------}--- | /O(n)/. Filter elements according to some predicate.-filter :: (a -> Bool) -> Queue a -> Queue a-filter pred (Queue xs ys zs)-  = balance xs' ys'-  where-    xs' = P.filter pred xs-    ys' = P.filter pred ys---- | /O(n)/. Partition the elements according to some predicate.-partition :: (a -> Bool) -> Queue a -> (Queue a,Queue a)-partition pred (Queue xs ys zs)-  = (balance xs1 ys1, balance xs2 ys2)-  where-    (xs1,xs2) = List.partition pred xs-    (ys1,ys2) = List.partition pred ys---{---------------------------------------------------------------------  Fold---------------------------------------------------------------------}--- | /O(n)/. Fold over the elements from left to right (ie. head to tail).-foldL :: (b -> a -> b) -> b -> Queue a -> b-foldL f z (Queue xs ys zs)-  = foldr (flip f) (foldl f z xs) ys---- | /O(n)/. Fold over the elements from right to left (ie. tail to head).-foldR :: (a -> b -> b) -> b -> Queue a -> b-foldR f z (Queue xs ys zs)-  = foldr f (foldl (flip f) z ys) xs---{---------------------------------------------------------------------  Conversion---------------------------------------------------------------------}--- | /O(n)/. The elements of a queue.-elems :: Queue a -> [a]-elems q-  = toList q---- | /O(n)/. Convert to a list.-toList :: Queue a -> [a]-toList (Queue xs ys zs)-  = xs ++ reverse ys---- | /O(n)/. Convert from a list.-fromList :: [a] -> Queue a-fromList xs-  = Queue xs [] xs---{---------------------------------------------------------------------  instance Eq, Show---------------------------------------------------------------------}-instance Eq a => Eq (Queue a) where-  q1 == q2  = toList q1 == toList q2--instance Show a => Show (Queue a) where-  showsPrec d q  = showsPrec d (toList q)---{---------------------------------------------------------------------  Smart constructor:-  Note that @(queue xs ys zs)@ is always called with -    @(length zs == length xs - length ys + 1)@. and thus-  @rotate@ is always called when @(length xs == length ys+1)@.---------------------------------------------------------------------}-balance :: [a] -> [a] -> Queue a-balance xs ys-  = Queue qs [] qs-  where-    qs = xs ++ reverse ys--queue :: [a] -> [a] -> [a] -> Queue a-queue xs ys (z:zs) = Queue xs ys zs-queue xs ys []     = Queue qs [] qs-                   where-                     qs = rotate xs ys []---- @(rotate xs ys []) == xs ++ reverse ys)@ -rotate :: [a] -> [a] -> [a] -> [a]-rotate []     [y]    zs  = y:zs-rotate (x:xs) (y:ys) zs  = x:rotate xs ys (y:zs) -rotate xs     ys     zs  = error "Queue.rotate: unbalanced queue"---valid :: Queue a -> Bool-valid (Queue xs ys zs)-  = (P.length zs == P.length xs - P.length ys) && (P.length ys <= P.length xs)--{--{---------------------------------------------------------------------  QuickCheck---------------------------------------------------------------------}-qcheck prop-  = check config prop-  where-    config = Config-      { configMaxTest = 500-      , configMaxFail = 10000-      , configSize    = \n -> (div n 2 + 3)-      , configEvery   = \n args -> let s = show n in s ++ [ '\b' | _ <- s ]-      }---{---------------------------------------------------------------------  Arbitrary, reasonably balanced queues---------------------------------------------------------------------}-instance Arbitrary a => Arbitrary (Queue a) where-  arbitrary = do{ qs <- arbitrary-                ; let (ys,xs) = splitAt (P.length qs `div` 2) qs-                ; return (Queue xs ys (xs ++ reverse ys))-                }---prop_Valid :: Queue Int -> Bool-prop_Valid q-  = valid q--prop_InsertLast :: [Int] -> Property-prop_InsertLast xs-  = not (null xs) ==> head (foldr insert empty xs) == last xs--prop_InsertValid :: [Int] -> Bool-prop_InsertValid xs-  = valid (foldr insert empty xs)--prop_Queue :: [Int] -> Bool-prop_Queue xs-  = toList (foldl (flip insert) empty xs) == foldr (:) [] xs-  -prop_List :: [Int] -> Bool-prop_List xs-  = toList (fromList xs) == xs--prop_TailValid :: [Int] -> Bool-prop_TailValid xs-  = valid (tail (foldr insert empty (1:xs)))--}-
− src/UU/DData/Scc.hs
@@ -1,309 +0,0 @@----------------------------------------------------------------------------------{-| Module      :  Scc-    Copyright   :  (c) Daan Leijen 2002-    License     :  BSD-style--    Maintainer  :  daan@cs.uu.nl-    Stability   :  provisional-    Portability :  portable--  Compute the /strongly connected components/ of a directed graph.-  The implementation is based on the following article:--  * David King and John Launchbury, /Lazy Depth-First Search and Linear Graph Algorithms in Haskell/,-    ACM Principles of Programming Languages, San Francisco, 1995.--  In contrast to their description, this module doesn't use lazy state-  threads but is instead purely functional -- using the "Map" and "Set" module.-  This means that the complexity of 'scc' is /O(n*log n)/ instead of /O(n)/ but-  due to the hidden constant factor, this implementation performs very well in practice.--}----------------------------------------------------------------------------------}-module UU.DData.Scc ( scc ) where--import qualified UU.DData.Map as Map-import qualified UU.DData.Set as Set --{---- just for testing-import Debug.QuickCheck       -import List(nub,sort)    --}--{---------------------------------------------------------------------  Graph---------------------------------------------------------------------}--- | A @Graph v@ is a directed graph with nodes @v@.-newtype Graph v = Graph (Map.Map v [v])---- | An @Edge v@ is a pair @(x,y)@ that represents an arrow from--- node @x@ to node @y@.-type Edge v     = (v,v)-type Node v     = (v,[v])--{---------------------------------------------------------------------  Conversion---------------------------------------------------------------------}-nodes :: Graph v -> [Node v]-nodes (Graph g)-  = Map.toList g--graph :: Ord v => [Node v] -> Graph v-graph es-  = Graph (Map.fromListWith (++) es)--{---------------------------------------------------------------------  Graph functions---------------------------------------------------------------------}-edges :: Graph v -> [Edge v]-edges g-  = [(v,w) | (v,vs) <- nodes g, w <- vs]--vertices :: Graph v -> [v]-vertices g-  = [v | (v,vs) <- nodes g]--successors :: Ord v => v -> Graph v -> [v]-successors v (Graph g)-  = Map.findWithDefault [] v g--transpose :: Ord v => Graph v -> Graph v-transpose g@(Graph m)-  = Graph (foldr add empty (edges g))-  where-    empty       = Map.map (const []) m-    add (v,w) m = Map.adjust (v:) w m---{---------------------------------------------------------------------  Depth first search and forests---------------------------------------------------------------------}-data Tree v   = Node v (Forest v) -type Forest v = [Tree v]--dff :: Ord v => Graph v -> Forest v-dff g-  = dfs g (vertices g)--dfs :: Ord v => Graph v -> [v] -> Forest v-dfs g vs      -  = prune (map (tree g) vs)--tree :: Ord v => Graph v -> v -> Tree v-tree g v  -  = Node v (map (tree g) (successors v g))--prune :: Ord v => Forest v -> Forest v-prune fs-  = snd (chop Set.empty  fs)-  where-    chop ms []  = (ms,[])-    chop ms (Node v vs:fs)-      | visited   = chop ms fs-      | otherwise = let ms0       = Set.insert v ms-                        (ms1,vs') = chop ms0 vs-                        (ms2,fs') = chop ms1 fs-                    in (ms2,Node v vs':fs')-      where-        visited   = Set.member v ms--{---------------------------------------------------------------------  Orderings---------------------------------------------------------------------}-preorder :: Ord v => Graph v -> [v]-preorder g-  = preorderF (dff g)--preorderF fs-  = concatMap preorderT fs--preorderT (Node v fs)-  = v:preorderF fs--postorder :: Ord v => Graph v -> [v]-postorder g-  = postorderF (dff g) --postorderT t-  = postorderF [t]--postorderF ts-  = postorderF' ts []-  where-    -- efficient concatenation by passing the tail around.-    postorderF' [] tl          = tl-    postorderF' (t:ts) tl      = postorderT' t (postorderF' ts tl)-    postorderT' (Node v fs) tl = postorderF' fs (v:tl)---{---------------------------------------------------------------------  Strongly connected components ---------------------------------------------------------------------}--{- | - Compute the strongly connected components of a graph. The algorithm- is tailored toward the needs of compiler writers that need to compute- recursive binding groups (for example, the original order is preserved- as much as possible). - - The expression (@scc xs@) computes the strongly connectected components- of graph @xs@. A graph is a list of nodes @(v,ws)@ where @v@ is the node - label and @ws@ a list of nodes where @v@ points to, ie. there is an - arrow\/dependency from @v@ to each node in @ws@. Here is an example- of @scc@:-->  Scc\> scc [(0,[1]),(1,[1,2,3]),(2,[1]),(3,[]),(4,[])]->  [[3],[1,2],[0],[4]]-- In an expression @(scc xs)@, the graph @xs@ should contain an entry for - every node in the graph, ie:-->  all (`elem` nodes) targets->  where nodes   = map fst xs->        targets = concat (map snd xs)-- Furthermore, the returned components consist exactly of the original nodes:-->  sort (concat (scc xs)) == sort (map fst xs)-- The connected components are sorted by dependency, ie. there are- no arrows\/dependencies from left-to-right. Furthermore, the original order- is preserved as much as possible. --}-scc :: Ord v => [(v,[v])] -> [[v]]-scc nodes-  = sccG (graph nodes)--sccG :: Ord v => Graph v -> [[v]]-sccG g-  = map preorderT (sccF g)--sccF :: Ord v => Graph v -> Forest v-sccF g         -  = reverse (dfs (transpose g) (topsort g))--topsort g-  = reverse (postorder g)--{---------------------------------------------------------------------  Reachable and path---------------------------------------------------------------------}-reachable v g-  = preorderF (dfs g [v])--path v w g-  = elem w (reachable v g)---{---------------------------------------------------------------------  Show---------------------------------------------------------------------}-instance Show v => Show (Graph v) where-  showsPrec d (Graph m) = shows m-  -instance Show v => Show (Tree v) where-  showsPrec d (Node v []) = shows v -  showsPrec d (Node v fs) = shows v . showList fs---{---------------------------------------------------------------------  Quick Test---------------------------------------------------------------------}-tgraph0 :: Graph Int-tgraph0 = graph -          [(0,[1])-          ,(1,[2,1,3])-          ,(2,[1])-          ,(3,[])-          ]--tgraph1 = graph-          [  ('a',"jg") -          ,  ('b',"ia")-          ,  ('c',"he")-          ,  ('d',"")-          ,  ('e',"jhd")-          ,  ('f',"i")-          ,  ('g',"fb")-          ,  ('h',"")-          ]--{--{---------------------------------------------------------------------  Quickcheck---------------------------------------------------------------------}-qcheck prop-  = check config prop-  where-    config = Config-      { configMaxTest = 500-      , configMaxFail = 5000-      , configSize    = \n -> (div n 2 + 3)-      , configEvery   = \n args -> let s = show n in s ++ [ '\b' | _ <- s ]-      }---{---------------------------------------------------------------------  Arbitrary Graph's---------------------------------------------------------------------}-instance (Ord v,Arbitrary v) => Arbitrary (Graph v) where-  arbitrary   = sized arbgraph---arbgraph :: (Ord v,Arbitrary v) => Int -> Gen (Graph v)-arbgraph n-  = do nodes <- arbitrary-       g     <- mapM (targets nodes) nodes-       return (graph g)-  where-    targets nodes v-      = do sz <- choose (0,length nodes-1)-           ts <- mapM (target nodes) [1..sz]-           return (v,ts)-        -    target nodes _-      = do idx <- choose (0,length nodes-1)-           return (nodes!!idx)--{---------------------------------------------------------------------  Properties---------------------------------------------------------------------}-prop_ValidGraph :: Graph Int -> Bool-prop_ValidGraph g-  = all (`elem` srcs) targets-  where-    srcs    = map fst (nodes g)-    targets = concatMap snd (nodes g)---- all scc nodes are in the original graph and the other way around-prop_SccComplete :: Graph Int -> Bool-prop_SccComplete g-  = sort (concat (sccG g)) == sort (vertices g)---- all scc nodes have only backward dependencies-prop_SccForward :: Graph Int -> Bool-prop_SccForward g-  = all noforwards (zip prevs ss) -  where-    ss      = sccG g-    prevs   = scanl1 (++) ss--    noforwards (prev,xs)-      = all (noforward prev) xs-  -    noforward prev x-      = all (`elem` prev) (successors x g)---- all strongly connected components refer to each other-prop_SccConnected :: Graph Int -> Bool-prop_SccConnected g-  = all connected (sccG g)-  where-    connected xs-      = all (paths xs) xs--    paths xs x-      = all (\y -> path x y g) xs---}-
− src/UU/DData/Seq.hs
@@ -1,91 +0,0 @@----------------------------------------------------------------------------------{-| Module      :  Seq-    Copyright   :  (c) Daan Leijen 2002-    License     :  BSD-style--    Maintainer  :  daan@cs.uu.nl-    Stability   :  provisional-    Portability :  portable--  An implementation of John Hughes's efficient catenable sequence type. A lazy sequence-  @Seq a@ can be concatenated in /O(1)/ time. After-  construction, the sequence in converted in /O(n)/ time into a list.--}----------------------------------------------------------------------------------}-module UU.DData.Seq( -- * Type-            Seq-            -- * Operators-          , (<>)--            -- * Construction-          , empty-          , single-          , cons-          , append--            -- * Conversion-          , toList-          , fromList-          ) where---{---------------------------------------------------------------------  Operators---------------------------------------------------------------------}-infixr 5 <>---- | /O(1)/. Append two sequences, see 'append'.-(<>) :: Seq a -> Seq a -> Seq a-s <> t-  = append s t--{---------------------------------------------------------------------  Type---------------------------------------------------------------------}--- | Sequences of values @a@.-newtype Seq a = Seq ([a] -> [a])--{---------------------------------------------------------------------  Construction---------------------------------------------------------------------}--- | /O(1)/. Create an empty sequence.-empty :: Seq a-empty-  = Seq (\ts -> ts)---- | /O(1)/. Create a sequence of one element.-single :: a -> Seq a-single x-  = Seq (\ts -> x:ts)---- | /O(1)/. Put a value in front of a sequence.-cons :: a -> Seq a -> Seq a-cons x (Seq f)-  = Seq (\ts -> x:f ts)---- | /O(1)/. Append two sequences.-append :: Seq a -> Seq a -> Seq a-append (Seq f) (Seq g)-  = Seq (\ts -> f (g ts))---{---------------------------------------------------------------------  Conversion---------------------------------------------------------------------}--- | /O(n)/. Convert a sequence to a list.-toList :: Seq a -> [a]-toList (Seq f)-  = f []---- | /O(n)/. Create a sequence from a list.-fromList :: [a] -> Seq a-fromList xs-  = Seq (\ts -> xs++ts)--------
− src/UU/DData/Set.hs
@@ -1,1032 +0,0 @@----------------------------------------------------------------------------------{-| Module      :  Set-    Copyright   :  (c) Daan Leijen 2002-    License     :  BSD-style--    Maintainer  :  daan@cs.uu.nl-    Stability   :  provisional-    Portability :  portable--  An efficient implementation of sets. --  1) The 'filter' function clashes with the "Prelude". -      If you want to use "Set" unqualified, this function should be hidden.--      > import Prelude hiding (filter)-      > import Set--      Another solution is to use qualified names. This is also the only way how-      a "Map", "Set", and "MultiSet" can be used within one module. --      > import qualified Set-      >-      > ... Set.single "Paris" --      Or, if you prefer a terse coding style:--      > import qualified Set as S-      >-      > ... S.single "Berlin" -  -  2) The implementation of "Set" is based on /size balanced/ binary trees (or-     trees of /bounded balance/) as described by:--     * Stephen Adams, \"/Efficient sets: a balancing act/\", Journal of Functional-       Programming 3(4):553-562, October 1993, <http://www.swiss.ai.mit.edu/~adams/BB>.--     * J. Nievergelt and E.M. Reingold, \"/Binary search trees of bounded balance/\",-       SIAM journal of computing 2(1), March 1973.--  3) Note that the implementation /left-biased/ -- the elements of a first argument-      are always perferred to the second, for example in 'union' or 'insert'.-      Off course, left-biasing can only be observed when equality an equivalence relation-      instead of structural equality.--  4) Another implementation of sets based on size balanced trees-      exists as "Data.Set" in the Ghc libraries. The good part about this library -      is that it is highly tuned and thorougly tested. However, it is also fairly old, -      it is implemented indirectly on top of "Data.FiniteMap" and only supports -      the basic set operations. -      The "Set" module overcomes some of these issues:-        -      * It tries to export a more complete and consistent set of operations, like-        'partition', 'subset' etc. --      * It uses the efficient /hedge/ algorithm for both 'union' and 'difference'-        (a /hedge/ algorithm is not applicable to 'intersection').-      -      * It converts ordered lists in linear time ('fromAscList').  --      * It takes advantage of the module system with names like 'empty' instead of 'Data.Set.emptySet'.-      -      * It is implemented directly, instead of using a seperate finite map implementation. --}-----------------------------------------------------------------------------------module UU.DData.Set  ( -            -- * Set type-              Set          -- instance Eq,Show--            -- * Operators-            , (\\)--            -- * Query-            , isEmpty-            , size-            , member-            , subset-            , properSubset-            -            -- * Construction-            , empty-            , single-            , insert-            , delete-            -            -- * Combine-            , union, unions-            , difference-            , intersection-            -            -- * Filter-            , filter-            , partition-            , split-            , splitMember--            -- * Fold-            , fold--            -- * Min\/Max-            , findMin-            , findMax-            , deleteMin-            , deleteMax-            , deleteFindMin-            , deleteFindMax--            -- * Conversion--            -- ** List-            , elems-            , toList-            , fromList-            -            -- ** Ordered list-            , toAscList-            , fromAscList-            , fromDistinctAscList-                        -            -- * Debugging-            , showTree-            , showTreeWith-            , valid-            ) where--import Prelude hiding (filter)--{---- just for testing-import QuickCheck -import List (nub,sort)-import qualified List--}--{---------------------------------------------------------------------  Operators---------------------------------------------------------------------}-infixl 9 \\ ------ | /O(n+m)/. See 'difference'.-(\\) :: Ord a => Set a -> Set a -> Set a-m1 \\ m2 = difference m1 m2--{---------------------------------------------------------------------  Sets are size balanced trees---------------------------------------------------------------------}--- | A set of values @a@.-data Set a    = Tip -              | Bin !Size a !(Set a) !(Set a) --type Size     = Int--{---------------------------------------------------------------------  Query---------------------------------------------------------------------}--- | /O(1)/. Is this the empty set?-isEmpty :: Set a -> Bool-isEmpty t-  = case t of-      Tip           -> True-      Bin sz x l r  -> False---- | /O(1)/. The number of elements in the set.-size :: Set a -> Int-size t-  = case t of-      Tip           -> 0-      Bin sz x l r  -> sz---- | /O(log n)/. Is the element in the set?-member :: Ord a => a -> Set a -> Bool-member x t-  = case t of-      Tip -> False-      Bin sz y l r-          -> case compare x y of-               LT -> member x l-               GT -> member x r-               EQ -> True       --{---------------------------------------------------------------------  Construction---------------------------------------------------------------------}--- | /O(1)/. The empty set.-empty  :: Set a-empty-  = Tip---- | /O(1)/. Create a singleton set.-single :: a -> Set a-single x -  = Bin 1 x Tip Tip--{---------------------------------------------------------------------  Insertion, Deletion---------------------------------------------------------------------}--- | /O(log n)/. Insert an element in a set.-insert :: Ord a => a -> Set a -> Set a-insert x t-  = case t of-      Tip -> single x-      Bin sz y l r-          -> case compare x y of-               LT -> balance y (insert x l) r-               GT -> balance y l (insert x r)-               EQ -> Bin sz x l r----- | /O(log n)/. Delete an element from a set.-delete :: Ord a => a -> Set a -> Set a-delete x t-  = case t of-      Tip -> Tip-      Bin sz y l r -          -> case compare x y of-               LT -> balance y (delete x l) r-               GT -> balance y l (delete x r)-               EQ -> glue l r--{---------------------------------------------------------------------  Subset---------------------------------------------------------------------}--- | /O(n+m)/. Is this a proper subset? (ie. a subset but not equal).-properSubset :: Ord a => Set a -> Set a -> Bool-properSubset s1 s2-  = (size s1 < size s2) && (subset s1 s2)----- | /O(n+m)/. Is this a subset?-subset :: Ord a => Set a -> Set a -> Bool-subset t1 t2-  = (size t1 <= size t2) && (subsetX t1 t2)--subsetX Tip t = True-subsetX t Tip = False-subsetX (Bin _ x l r) t-  = found && subsetX l lt && subsetX r gt-  where-    (found,lt,gt) = splitMember x t---{---------------------------------------------------------------------  Minimal, Maximal---------------------------------------------------------------------}--- | /O(log n)/. The minimal element of a set.-findMin :: Set a -> a-findMin (Bin _ x Tip r) = x-findMin (Bin _ x l r)   = findMin l-findMin Tip             = error "Set.findMin: empty set has no minimal element"---- | /O(log n)/. The maximal element of a set.-findMax :: Set a -> a-findMax (Bin _ x l Tip)  = x-findMax (Bin _ x l r)    = findMax r-findMax Tip              = error "Set.findMax: empty set has no maximal element"---- | /O(log n)/. Delete the minimal element.-deleteMin :: Set a -> Set a-deleteMin (Bin _ x Tip r) = r-deleteMin (Bin _ x l r)   = balance x (deleteMin l) r-deleteMin Tip             = Tip---- | /O(log n)/. Delete the maximal element.-deleteMax :: Set a -> Set a-deleteMax (Bin _ x l Tip) = l-deleteMax (Bin _ x l r)   = balance x l (deleteMax r)-deleteMax Tip             = Tip---{---------------------------------------------------------------------  Union. ---------------------------------------------------------------------}--- | The union of a list of sets: (@unions == foldl union empty@).-unions :: Ord a => [Set a] -> Set a-unions ts-  = foldlStrict union empty ts----- | /O(n+m)/. The union of two sets. Uses the efficient /hedge-union/ algorithm.-union :: Ord a => Set a -> Set a -> Set a-union Tip t2  = t2-union t1 Tip  = t1-union t1 t2  -- hedge-union is more efficient on (bigset `union` smallset)-  | size t1 >= size t2  = hedgeUnion (const LT) (const GT) t1 t2-  | otherwise           = hedgeUnion (const LT) (const GT) t2 t1--hedgeUnion cmplo cmphi t1 Tip -  = t1-hedgeUnion cmplo cmphi Tip (Bin _ x l r)-  = join x (filterGt cmplo l) (filterLt cmphi r)-hedgeUnion cmplo cmphi (Bin _ x l r) t2-  = join x (hedgeUnion cmplo cmpx l (trim cmplo cmpx t2)) -           (hedgeUnion cmpx cmphi r (trim cmpx cmphi t2))-  where-    cmpx y  = compare x y--{---------------------------------------------------------------------  Difference---------------------------------------------------------------------}--- | /O(n+m)/. Difference of two sets. --- The implementation uses an efficient /hedge/ algorithm comparable with /hedge-union/.-difference :: Ord a => Set a -> Set a -> Set a-difference Tip t2  = Tip-difference t1 Tip  = t1-difference t1 t2   = hedgeDiff (const LT) (const GT) t1 t2--hedgeDiff cmplo cmphi Tip t     -  = Tip-hedgeDiff cmplo cmphi (Bin _ x l r) Tip -  = join x (filterGt cmplo l) (filterLt cmphi r)-hedgeDiff cmplo cmphi t (Bin _ x l r) -  = merge (hedgeDiff cmplo cmpx (trim cmplo cmpx t) l) -          (hedgeDiff cmpx cmphi (trim cmpx cmphi t) r)-  where-    cmpx y = compare x y--{---------------------------------------------------------------------  Intersection---------------------------------------------------------------------}--- | /O(n+m)/. The intersection of two sets.-intersection :: Ord a => Set a -> Set a -> Set a-intersection Tip t = Tip-intersection t Tip = Tip-intersection t1 t2  -- intersection is more efficient on (bigset `intersection` smallset)-  | size t1 >= size t2  = intersect t1 t2-  | otherwise           = intersect t2 t1--intersect Tip t = Tip-intersect t Tip = Tip-intersect t (Bin _ x l r)-  | found     = join x tl tr-  | otherwise = merge tl tr-  where-    (found,lt,gt) = splitMember x t-    tl            = intersect lt l-    tr            = intersect gt r---{---------------------------------------------------------------------  Filter and partition---------------------------------------------------------------------}--- | /O(n)/. Filter all elements that satisfy the predicate.-filter :: Ord a => (a -> Bool) -> Set a -> Set a-filter p Tip = Tip-filter p (Bin _ x l r)-  | p x       = join x (filter p l) (filter p r)-  | otherwise = merge (filter p l) (filter p r)---- | /O(n)/. Partition the set into two sets, one with all elements that satisfy--- the predicate and one with all elements that don't satisfy the predicate.--- See also 'split'.-partition :: Ord a => (a -> Bool) -> Set a -> (Set a,Set a)-partition p Tip = (Tip,Tip)-partition p (Bin _ x l r)-  | p x       = (join x l1 r1,merge l2 r2)-  | otherwise = (merge l1 r1,join x l2 r2)-  where-    (l1,l2) = partition p l-    (r1,r2) = partition p r--{---------------------------------------------------------------------  Fold---------------------------------------------------------------------}--- | /O(n)/. Fold the elements of a set.-fold :: (a -> b -> b) -> b -> Set a -> b-fold f z s-  = foldR f z s---- | /O(n)/. Post-order fold.-foldR :: (a -> b -> b) -> b -> Set a -> b-foldR f z Tip           = z-foldR f z (Bin _ x l r) = foldR f (f x (foldR f z r)) l---{---------------------------------------------------------------------  List variations ---------------------------------------------------------------------}--- | /O(n)/. The elements of a set.-elems :: Set a -> [a]-elems s-  = toList s--{---------------------------------------------------------------------  Lists ---------------------------------------------------------------------}--- | /O(n)/. Convert the set to a list of elements.-toList :: Set a -> [a]-toList s-  = toAscList s---- | /O(n)/. Convert the set to an ascending list of elements.-toAscList :: Set a -> [a]-toAscList t   -  = foldR (:) [] t----- | /O(n*log n)/. Create a set from a list of elements.-fromList :: Ord a => [a] -> Set a -fromList xs -  = foldlStrict ins empty xs-  where-    ins t x = insert x t--{---------------------------------------------------------------------  Building trees from ascending/descending lists can be done in linear time.-  -  Note that if [xs] is ascending that: -    fromAscList xs == fromList xs---------------------------------------------------------------------}--- | /O(n)/. Build a map from an ascending list in linear time.-fromAscList :: Eq a => [a] -> Set a -fromAscList xs-  = fromDistinctAscList (combineEq xs)-  where-  -- [combineEq xs] combines equal elements with [const] in an ordered list [xs]-  combineEq xs-    = case xs of-        []     -> []-        [x]    -> [x]-        (x:xx) -> combineEq' x xx--  combineEq' z [] = [z]-  combineEq' z (x:xs)-    | z==x      = combineEq' z xs-    | otherwise = z:combineEq' x xs----- | /O(n)/. Build a set from an ascending list of distinct elements in linear time.-fromDistinctAscList :: [a] -> Set a -fromDistinctAscList xs-  = build const (length xs) xs-  where-    -- 1) use continutations so that we use heap space instead of stack space.-    -- 2) special case for n==5 to build bushier trees. -    build c 0 xs   = c Tip xs -    build c 5 xs   = case xs of-                       (x1:x2:x3:x4:x5:xx) -                            -> c (bin x4 (bin x2 (single x1) (single x3)) (single x5)) xx-    build c n xs   = seq nr $ build (buildR nr c) nl xs-                   where-                     nl = n `div` 2-                     nr = n - nl - 1--    buildR n c l (x:ys) = build (buildB l x c) n ys-    buildB l x c r zs   = c (bin x l r) zs--{---------------------------------------------------------------------  Eq converts the set to a list. In a lazy setting, this -  actually seems one of the faster methods to compare two trees -  and it is certainly the simplest :-)---------------------------------------------------------------------}-instance Eq a => Eq (Set a) where-  t1 == t2  = (size t1 == size t2) && (toAscList t1 == toAscList t2)--{---------------------------------------------------------------------  Show---------------------------------------------------------------------}-instance Show a => Show (Set a) where-  showsPrec d s  = showSet (toAscList s)--showSet :: (Show a) => [a] -> ShowS-showSet []     -  = showString "{}" -showSet (x:xs) -  = showChar '{' . shows x . showTail xs-  where-    showTail []     = showChar '}'-    showTail (x:xs) = showChar ',' . shows x . showTail xs-    --{---------------------------------------------------------------------  Utility functions that return sub-ranges of the original-  tree. Some functions take a comparison function as argument to-  allow comparisons against infinite values. A function [cmplo x]-  should be read as [compare lo x].--  [trim cmplo cmphi t]  A tree that is either empty or where [cmplo x == LT]-                        and [cmphi x == GT] for the value [x] of the root.-  [filterGt cmp t]      A tree where for all values [k]. [cmp k == LT]-  [filterLt cmp t]      A tree where for all values [k]. [cmp k == GT]--  [split k t]           Returns two trees [l] and [r] where all values-                        in [l] are <[k] and all keys in [r] are >[k].-  [splitMember k t]     Just like [split] but also returns whether [k]-                        was found in the tree.---------------------------------------------------------------------}--{---------------------------------------------------------------------  [trim lo hi t] trims away all subtrees that surely contain no-  values between the range [lo] to [hi]. The returned tree is either-  empty or the key of the root is between @lo@ and @hi@.---------------------------------------------------------------------}-trim :: (a -> Ordering) -> (a -> Ordering) -> Set a -> Set a-trim cmplo cmphi Tip = Tip-trim cmplo cmphi t@(Bin sx x l r)-  = case cmplo x of-      LT -> case cmphi x of-              GT -> t-              le -> trim cmplo cmphi l-      ge -> trim cmplo cmphi r-              -trimMemberLo :: Ord a => a -> (a -> Ordering) -> Set a -> (Bool, Set a)-trimMemberLo lo cmphi Tip = (False,Tip)-trimMemberLo lo cmphi t@(Bin sx x l r)-  = case compare lo x of-      LT -> case cmphi x of-              GT -> (member lo t, t)-              le -> trimMemberLo lo cmphi l-      GT -> trimMemberLo lo cmphi r-      EQ -> (True,trim (compare lo) cmphi r)---{---------------------------------------------------------------------  [filterGt x t] filter all values >[x] from tree [t]-  [filterLt x t] filter all values <[x] from tree [t]---------------------------------------------------------------------}-filterGt :: (a -> Ordering) -> Set a -> Set a-filterGt cmp Tip = Tip-filterGt cmp (Bin sx x l r)-  = case cmp x of-      LT -> join x (filterGt cmp l) r-      GT -> filterGt cmp r-      EQ -> r-      -filterLt :: (a -> Ordering) -> Set a -> Set a-filterLt cmp Tip = Tip-filterLt cmp (Bin sx x l r)-  = case cmp x of-      LT -> filterLt cmp l-      GT -> join x l (filterLt cmp r)-      EQ -> l---{---------------------------------------------------------------------  Split---------------------------------------------------------------------}--- | /O(log n)/. The expression (@split x set@) is a pair @(set1,set2)@--- where all elements in @set1@ are lower than @x@ and all elements in--- @set2@ larger than @x@.-split :: Ord a => a -> Set a -> (Set a,Set a)-split x Tip = (Tip,Tip)-split x (Bin sy y l r)-  = case compare x y of-      LT -> let (lt,gt) = split x l in (lt,join y gt r)-      GT -> let (lt,gt) = split x r in (join y l lt,gt)-      EQ -> (l,r)---- | /O(log n)/. Performs a 'split' but also returns whether the pivot--- element was found in the original set.-splitMember :: Ord a => a -> Set a -> (Bool,Set a,Set a)-splitMember x Tip = (False,Tip,Tip)-splitMember x (Bin sy y l r)-  = case compare x y of-      LT -> let (found,lt,gt) = splitMember x l in (found,lt,join y gt r)-      GT -> let (found,lt,gt) = splitMember x r in (found,join y l lt,gt)-      EQ -> (True,l,r)--{---------------------------------------------------------------------  Utility functions that maintain the balance properties of the tree.-  All constructors assume that all values in [l] < [x] and all values-  in [r] > [x], and that [l] and [r] are valid trees.-  -  In order of sophistication:-    [Bin sz x l r]    The type constructor.-    [bin x l r]       Maintains the correct size, assumes that both [l]-                      and [r] are balanced with respect to each other.-    [balance x l r]   Restores the balance and size.-                      Assumes that the original tree was balanced and-                      that [l] or [r] has changed by at most one element.-    [join x l r]      Restores balance and size. --  Furthermore, we can construct a new tree from two trees. Both operations-  assume that all values in [l] < all values in [r] and that [l] and [r]-  are valid:-    [glue l r]        Glues [l] and [r] together. Assumes that [l] and-                      [r] are already balanced with respect to each other.-    [merge l r]       Merges two trees and restores balance.--  Note: in contrast to Adam's paper, we use (<=) comparisons instead-  of (<) comparisons in [join], [merge] and [balance]. -  Quickcheck (on [difference]) showed that this was necessary in order -  to maintain the invariants. It is quite unsatisfactory that I haven't -  been able to find out why this is actually the case! Fortunately, it -  doesn't hurt to be a bit more conservative.---------------------------------------------------------------------}--{---------------------------------------------------------------------  Join ---------------------------------------------------------------------}-join :: a -> Set a -> Set a -> Set a-join x Tip r  = insertMin x r-join x l Tip  = insertMax x l-join x l@(Bin sizeL y ly ry) r@(Bin sizeR z lz rz)-  | delta*sizeL <= sizeR  = balance z (join x l lz) rz-  | delta*sizeR <= sizeL  = balance y ly (join x ry r)-  | otherwise             = bin x l r----- insertMin and insertMax don't perform potentially expensive comparisons.-insertMax,insertMin :: a -> Set a -> Set a -insertMax x t-  = case t of-      Tip -> single x-      Bin sz y l r-          -> balance y l (insertMax x r)-             -insertMin x t-  = case t of-      Tip -> single x-      Bin sz y l r-          -> balance y (insertMin x l) r-             -{---------------------------------------------------------------------  [merge l r]: merges two trees.---------------------------------------------------------------------}-merge :: Set a -> Set a -> Set a-merge Tip r   = r-merge l Tip   = l-merge l@(Bin sizeL x lx rx) r@(Bin sizeR y ly ry)-  | delta*sizeL <= sizeR = balance y (merge l ly) ry-  | delta*sizeR <= sizeL = balance x lx (merge rx r)-  | otherwise            = glue l r--{---------------------------------------------------------------------  [glue l r]: glues two trees together.-  Assumes that [l] and [r] are already balanced with respect to each other.---------------------------------------------------------------------}-glue :: Set a -> Set a -> Set a-glue Tip r = r-glue l Tip = l-glue l r   -  | size l > size r = let (m,l') = deleteFindMax l in balance m l' r-  | otherwise       = let (m,r') = deleteFindMin r in balance m l r'----- | /O(log n)/. Delete and find the minimal element.-deleteFindMin :: Set a -> (a,Set a)-deleteFindMin t -  = case t of-      Bin _ x Tip r -> (x,r)-      Bin _ x l r   -> let (xm,l') = deleteFindMin l in (xm,balance x l' r)-      Tip           -> (error "Set.deleteFindMin: can not return the minimal element of an empty set", Tip)---- | /O(log n)/. Delete and find the maximal element.-deleteFindMax :: Set a -> (a,Set a)-deleteFindMax t-  = case t of-      Bin _ x l Tip -> (x,l)-      Bin _ x l r   -> let (xm,r') = deleteFindMax r in (xm,balance x l r')-      Tip           -> (error "Set.deleteFindMax: can not return the maximal element of an empty set", Tip)---{---------------------------------------------------------------------  [balance x l r] balances two trees with value x.-  The sizes of the trees should balance after decreasing the-  size of one of them. (a rotation).--  [delta] is the maximal relative difference between the sizes of-          two trees, it corresponds with the [w] in Adams' paper,-          or equivalently, [1/delta] corresponds with the $\alpha$-          in Nievergelt's paper. Adams shows that [delta] should-          be larger than 3.745 in order to garantee that the-          rotations can always restore balance.         --  [ratio] is the ratio between an outer and inner sibling of the-          heavier subtree in an unbalanced setting. It determines-          whether a double or single rotation should be performed-          to restore balance. It is correspondes with the inverse-          of $\alpha$ in Adam's article.--  Note that:-  - [delta] should be larger than 4.646 with a [ratio] of 2.-  - [delta] should be larger than 3.745 with a [ratio] of 1.534.-  -  - A lower [delta] leads to a more 'perfectly' balanced tree.-  - A higher [delta] performs less rebalancing.--  - Balancing is automatic for random data and a balancing-    scheme is only necessary to avoid pathological worst cases.-    Almost any choice will do in practice-    -  - Allthough it seems that a rather large [delta] may perform better -    than smaller one, measurements have shown that the smallest [delta]-    of 4 is actually the fastest on a wide range of operations. It-    especially improves performance on worst-case scenarios like-    a sequence of ordered insertions.--  Note: in contrast to Adams' paper, we use a ratio of (at least) 2-  to decide whether a single or double rotation is needed. Allthough-  he actually proves that this ratio is needed to maintain the-  invariants, his implementation uses a (invalid) ratio of 1. -  He is aware of the problem though since he has put a comment in his -  original source code that he doesn't care about generating a -  slightly inbalanced tree since it doesn't seem to matter in practice. -  However (since we use quickcheck :-) we will stick to strictly balanced -  trees.---------------------------------------------------------------------}-delta,ratio :: Int-delta = 4-ratio = 2--balance :: a -> Set a -> Set a -> Set a-balance x l r-  | sizeL + sizeR <= 1    = Bin sizeX x l r-  | sizeR >= delta*sizeL  = rotateL x l r-  | sizeL >= delta*sizeR  = rotateR x l r-  | otherwise             = Bin sizeX x l r-  where-    sizeL = size l-    sizeR = size r-    sizeX = sizeL + sizeR + 1---- rotate-rotateL x l r@(Bin _ _ ly ry)-  | size ly < ratio*size ry = singleL x l r-  | otherwise               = doubleL x l r--rotateR x l@(Bin _ _ ly ry) r-  | size ry < ratio*size ly = singleR x l r-  | otherwise               = doubleR x l r---- basic rotations-singleL x1 t1 (Bin _ x2 t2 t3)  = bin x2 (bin x1 t1 t2) t3-singleR x1 (Bin _ x2 t1 t2) t3  = bin x2 t1 (bin x1 t2 t3)--doubleL x1 t1 (Bin _ x2 (Bin _ x3 t2 t3) t4) = bin x3 (bin x1 t1 t2) (bin x2 t3 t4)-doubleR x1 (Bin _ x2 t1 (Bin _ x3 t2 t3)) t4 = bin x3 (bin x2 t1 t2) (bin x1 t3 t4)---{---------------------------------------------------------------------  The bin constructor maintains the size of the tree---------------------------------------------------------------------}-bin :: a -> Set a -> Set a -> Set a-bin x l r-  = Bin (size l + size r + 1) x l r---{---------------------------------------------------------------------  Utilities---------------------------------------------------------------------}-foldlStrict f z xs-  = case xs of-      []     -> z-      (x:xx) -> let z' = f z x in seq z' (foldlStrict f z' xx)---{---------------------------------------------------------------------  Debugging---------------------------------------------------------------------}--- | /O(n)/. Show the tree that implements the set. The tree is shown--- in a compressed, hanging format.-showTree :: Show a => Set a -> String-showTree s-  = showTreeWith True False s---{- | /O(n)/. 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.--> Set> putStrLn $ showTreeWith True False $ fromDistinctAscList [1..5]-> 4-> +--2-> |  +--1-> |  +--3-> +--5-> -> Set> putStrLn $ showTreeWith True True $ fromDistinctAscList [1..5]-> 4-> |-> +--2-> |  |-> |  +--1-> |  |-> |  +--3-> |-> +--5-> -> Set> putStrLn $ showTreeWith False True $ fromDistinctAscList [1..5]-> +--5-> |-> 4-> |-> |  +--3-> |  |-> +--2->    |->    +--1---}-showTreeWith :: Show a => Bool -> Bool -> Set a -> String-showTreeWith hang wide t-  | hang      = (showsTreeHang wide [] t) ""-  | otherwise = (showsTree wide [] [] t) ""--showsTree :: Show a => Bool -> [String] -> [String] -> Set a -> ShowS-showsTree wide lbars rbars t-  = case t of-      Tip -> showsBars lbars . showString "|\n"-      Bin sz x Tip Tip-          -> showsBars lbars . shows x . showString "\n" -      Bin sz x l r-          -> showsTree wide (withBar rbars) (withEmpty rbars) r .-             showWide wide rbars .-             showsBars lbars . shows x . showString "\n" .-             showWide wide lbars .-             showsTree wide (withEmpty lbars) (withBar lbars) l--showsTreeHang :: Show a => Bool -> [String] -> Set a -> ShowS-showsTreeHang wide bars t-  = case t of-      Tip -> showsBars bars . showString "|\n" -      Bin sz x Tip Tip-          -> showsBars bars . shows x . showString "\n" -      Bin sz x l r-          -> showsBars bars . shows x . showString "\n" . -             showWide wide bars .-             showsTreeHang wide (withBar bars) l .-             showWide wide bars .-             showsTreeHang wide (withEmpty bars) r---showWide wide bars -  | wide      = showString (concat (reverse bars)) . showString "|\n" -  | otherwise = id--showsBars :: [String] -> ShowS-showsBars bars-  = case bars of-      [] -> id-      _  -> showString (concat (reverse (tail bars))) . showString node--node           = "+--"-withBar bars   = "|  ":bars-withEmpty bars = "   ":bars--{---------------------------------------------------------------------  Assertions---------------------------------------------------------------------}--- | /O(n)/. Test if the internal set structure is valid.-valid :: Ord a => Set a -> Bool-valid t-  = balanced t && ordered t && validsize t--ordered t-  = bounded (const True) (const True) t-  where-    bounded lo hi t-      = case t of-          Tip           -> True-          Bin sz x l r  -> (lo x) && (hi x) && bounded lo (<x) l && bounded (>x) hi r--balanced :: Set a -> Bool-balanced t-  = case t of-      Tip           -> True-      Bin sz x l r  -> (size l + size r <= 1 || (size l <= delta*size r && size r <= delta*size l)) &&-                       balanced l && balanced r---validsize t-  = (realsize t == Just (size t))-  where-    realsize t-      = case t of-          Tip          -> Just 0-          Bin sz x l r -> case (realsize l,realsize r) of-                            (Just n,Just m)  | n+m+1 == sz  -> Just sz-                            other            -> Nothing--{--{---------------------------------------------------------------------  Testing---------------------------------------------------------------------}-testTree :: [Int] -> Set Int-testTree xs   = fromList xs-test1 = testTree [1..20]-test2 = testTree [30,29..10]-test3 = testTree [1,4,6,89,2323,53,43,234,5,79,12,9,24,9,8,423,8,42,4,8,9,3]--{---------------------------------------------------------------------  QuickCheck---------------------------------------------------------------------}-qcheck prop-  = check config prop-  where-    config = Config-      { configMaxTest = 500-      , configMaxFail = 5000-      , configSize    = \n -> (div n 2 + 3)-      , configEvery   = \n args -> let s = show n in s ++ [ '\b' | _ <- s ]-      }---{---------------------------------------------------------------------  Arbitrary, reasonably balanced trees---------------------------------------------------------------------}-instance (Enum a) => Arbitrary (Set a) where-  arbitrary = sized (arbtree 0 maxkey)-            where maxkey  = 10000--arbtree :: (Enum a) => Int -> Int -> Int -> Gen (Set a)-arbtree lo hi n-  | n <= 0        = return Tip-  | lo >= hi      = return Tip-  | otherwise     = do{ i  <- choose (lo,hi)-                      ; m  <- choose (1,30)-                      ; let (ml,mr)  | m==(1::Int)= (1,2)-                                     | m==2       = (2,1)-                                     | m==3       = (1,1)-                                     | otherwise  = (2,2)-                      ; l  <- arbtree lo (i-1) (n `div` ml)-                      ; r  <- arbtree (i+1) hi (n `div` mr)-                      ; return (bin (toEnum i) l r)-                      }  ---{---------------------------------------------------------------------  Valid tree's---------------------------------------------------------------------}-forValid :: (Enum a,Show a,Testable b) => (Set a -> b) -> Property-forValid f-  = forAll arbitrary $ \t -> ---    classify (balanced t) "balanced" $-    classify (size t == 0) "empty" $-    classify (size t > 0  && size t <= 10) "small" $-    classify (size t > 10 && size t <= 64) "medium" $-    classify (size t > 64) "large" $-    balanced t ==> f t--forValidIntTree :: Testable a => (Set Int -> a) -> Property-forValidIntTree f-  = forValid f--forValidUnitTree :: Testable a => (Set Int -> a) -> Property-forValidUnitTree f-  = forValid f---prop_Valid -  = forValidUnitTree $ \t -> valid t--{---------------------------------------------------------------------  Single, Insert, Delete---------------------------------------------------------------------}-prop_Single :: Int -> Bool-prop_Single x-  = (insert x empty == single x)--prop_InsertValid :: Int -> Property-prop_InsertValid k-  = forValidUnitTree $ \t -> valid (insert k t)--prop_InsertDelete :: Int -> Set Int -> Property-prop_InsertDelete k t-  = not (member k t) ==> delete k (insert k t) == t--prop_DeleteValid :: Int -> Property-prop_DeleteValid k-  = forValidUnitTree $ \t -> -    valid (delete k (insert k t))--{---------------------------------------------------------------------  Balance---------------------------------------------------------------------}-prop_Join :: Int -> Property -prop_Join x-  = forValidUnitTree $ \t ->-    let (l,r) = split x t-    in valid (join x l r)--prop_Merge :: Int -> Property -prop_Merge x-  = forValidUnitTree $ \t ->-    let (l,r) = split x t-    in valid (merge l r)---{---------------------------------------------------------------------  Union---------------------------------------------------------------------}-prop_UnionValid :: Property-prop_UnionValid-  = forValidUnitTree $ \t1 ->-    forValidUnitTree $ \t2 ->-    valid (union t1 t2)--prop_UnionInsert :: Int -> Set Int -> Bool-prop_UnionInsert x t-  = union t (single x) == insert x t--prop_UnionAssoc :: Set Int -> Set Int -> Set Int -> Bool-prop_UnionAssoc t1 t2 t3-  = union t1 (union t2 t3) == union (union t1 t2) t3--prop_UnionComm :: Set Int -> Set Int -> Bool-prop_UnionComm t1 t2-  = (union t1 t2 == union t2 t1)---prop_DiffValid-  = forValidUnitTree $ \t1 ->-    forValidUnitTree $ \t2 ->-    valid (difference t1 t2)--prop_Diff :: [Int] -> [Int] -> Bool-prop_Diff xs ys-  =  toAscList (difference (fromList xs) (fromList ys))-    == List.sort ((List.\\) (nub xs)  (nub ys))--prop_IntValid-  = forValidUnitTree $ \t1 ->-    forValidUnitTree $ \t2 ->-    valid (intersection t1 t2)--prop_Int :: [Int] -> [Int] -> Bool-prop_Int xs ys-  =  toAscList (intersection (fromList xs) (fromList ys))-    == List.sort (nub ((List.intersect) (xs)  (ys)))--{---------------------------------------------------------------------  Lists---------------------------------------------------------------------}-prop_Ordered-  = forAll (choose (5,100)) $ \n ->-    let xs = [0..n::Int]-    in fromAscList xs == fromList xs--prop_List :: [Int] -> Bool-prop_List xs-  = (sort (nub xs) == toList (fromList xs))--}
src/UU/Parsing/Offside.hs view
@@ -5,7 +5,9 @@                          , pOpen                           , pClose                           , pSeparator -                         , scanOffside +                         , scanOffside+                         , scanOffsideWithTriggers+                         , OffsideTrigger(..)                          , OffsideSymbol(..)                          , OffsideInput                          , Stream@@ -13,100 +15,118 @@                          ) where                           import GHC.Prim+import Data.Maybe import UU.Parsing.Interface import UU.Parsing.Machine import UU.Parsing.Derived(opt, pFoldr1Sep,pList,pList1, pList1Sep) import UU.Scanner.Position -data OffsideSymbol s = -                Symbol s-              | SemiColon-              | CloseBrace-              | OpenBrace-              deriving (Ord,Eq,Show)+data OffsideTrigger+  = Trigger_IndentGT+  | Trigger_IndentGE+  deriving Eq +data OffsideSymbol s+  = Symbol s+  | SemiColon+  | CloseBrace+  | OpenBrace+  deriving (Ord,Eq,Show) +data Stream inp s p+  = Cons (OffsideSymbol s) (OffsideInput inp s p) +  | End inp++data IndentContext+  = Cxt     Bool                -- properties: allows nesting on equal indentation (triggered by Trigger_IndentGE)+            Int					-- indentation++data OffsideInput inp s p+  = Off p                                   -- position+        (Stream inp s p)                    -- input stream+        (Maybe (OffsideInput inp s p))      -- next in stack of nested OffsideInput's+ scanOffside :: (InputState i s p, Position p, Eq s)              =>  s ->  s -> s -> [s] -> i -> OffsideInput i s p  -scanOffside mod open close triggers ts = start ts []+scanOffside mod open close triggers ts+  = scanOffsideWithTriggers mod open close (zip (repeat Trigger_IndentGT) triggers) ts++scanOffsideWithTriggers :: (InputState i s p, Position p, Eq s) +            =>  s ->  s -> s -> [(OffsideTrigger,s)] -> i -> OffsideInput i s p  +scanOffsideWithTriggers mod open close triggers ts = start ts []  where- isModule  t = t == mod - isOpen    t = t == open- isClose   t = t == close- isTrigger t = t `elem` triggers+ isModule    t = t == mod + isOpen      t = t == open+ isClose     t = t == close+ isTrigger tr  = \t -> t `elem` triggers'+               where triggers' = [ s | (tr',s) <- triggers, tr == tr' ]+ isTriggerGT   = isTrigger Trigger_IndentGT+ isTriggerGE   = isTrigger Trigger_IndentGE  end ts    = Off (getPosition ts) (End ts)  cons :: p -> OffsideSymbol s -> OffsideInput i s p -> OffsideInput i s p  cons p s r =  Off p (Cons s r) Nothing    start = case splitStateE ts of-          Left' t _ | not (isModule t || isOpen t) -> implicitL 0 (column (getPosition ts) )+          Left' t _ | not (isModule t || isOpen t) -> implicitL 0 (Cxt False (column (getPosition ts)))           _                                        -> layoutL   0  - -- L (<n>:ts) (m:ms) 	= ; : (L ts (m:ms)) 	if m = n - --	                = } : (L (<n>:ts) ms) 	if n < m - -- L (<n>:ts) ms 	= L ts ms - startlnL l n ts (m:ms) | m == n  = cons (getPosition ts) SemiColon  (layoutL (line (getPosition ts)) ts (m:ms))    -                          | n <  m  = cons (getPosition ts) CloseBrace (startlnL l n ts ms)- startlnL l n ts ms               = layoutL (line (getPosition ts))  ts ms- -- L  ({n}:ts)  (m:ms) = { : (L  ts (n:m:ms))     if n > m    (Note  1) - -- L  ({n}:ts)  []     = { : (L  ts [n])          if n > 0    (Note  1) + -- L (<n>:ts) (m:ms)   = ; : (L ts (m:ms))     if m = n + --                     = } : (L (<n>:ts) ms)   if n < m + -- L (<n>:ts) ms       = L ts ms + startlnL  l n ts (m:ms) | m == n    = cons (getPosition ts) SemiColon  (layoutL (line (getPosition ts)) ts (m:ms))    +                         | n <  m    = cons (getPosition ts) CloseBrace (startlnL l n ts ms)+ startlnL  l n ts ms                 = layoutL (line (getPosition ts))  ts ms++ -- L  ({n}:ts)  (m:ms) = { : (L  ts (n:m:ms))     if n >  m    (Note  1) + -- L  ({n}:ts)  (m:ms) = { : (L  ts (n:m:ms))     if n >= m    (as per Haskell2010, inside a do only) + -- L  ({n}:ts)  []     = { : (L  ts [n])          if n >  0    (Note  1)   -- L  ({n}:ts)  ms     = { : } : (L  (<n>:ts) ms) (Note  2) - implicitL l n ts (m:ms) | n > m  = cons (getPosition ts) OpenBrace (layoutL (line (getPosition ts)) ts (n:m:ms))- implicitL l n ts []     | n > 0  = cons (getPosition ts) OpenBrace (layoutL (line (getPosition ts)) ts [n])- implicitL l n ts ms              = cons (getPosition ts) OpenBrace (cons (getPosition ts) CloseBrace (startlnL l n ts ms))- layoutL ln ts ms | ln /= sln = startln (column pos) ts ms-                    | otherwise     = sameln ts ms+ implicitL l (Cxt ge n) ts (m:ms) |     n >  m+                                    || (n >= m && ge)+                                              = cons (getPosition ts) OpenBrace (layoutL (line (getPosition ts)) ts (n:m:ms))+ implicitL l (Cxt _  n) ts []     | n >  0    = cons (getPosition ts) OpenBrace (layoutL (line (getPosition ts)) ts [n])+ implicitL l (Cxt _  n) ts ms                 = cons (getPosition ts) OpenBrace (cons (getPosition ts) CloseBrace (startlnL l n ts ms))++ layoutL   ln  ts ms     | ln /= sln = startln (column pos) ts ms+                         | otherwise = sameln ts ms       -  where sln = line pos-        pos   = getPosition ts+  where sln       = line pos+        pos       = getPosition ts         layout    = layoutL ln               implicit  = implicitL ln-        startln = startlnL ln    +        startln   = startlnL ln             -- If a let ,where ,do , or of keyword is not followed by the lexeme {,           -- the token {n} is inserted after the keyword, where nis the indentation of         -- the  next lexeme if there is one, or 0 if the end of file has been reached. -        aftertrigger ts ms = case splitStateE ts of-                                Left' t _  | isOpen t  -> layout ts ms-                                           | otherwise -> implicit (column(getPosition ts)) ts ms-                                Right' _               -> implicit 0 ts ms+        aftertrigger isTriggerGE ts ms+          = case splitStateE ts of+              Left' t _  | isOpen t  -> layout ts ms+                         | otherwise -> implicit (Cxt isTriggerGE (column(getPosition ts))) ts ms+              Right' _               -> implicit (Cxt False       0                       ) ts ms           -- L  ( }:ts)  (0:ms) = } : (L  ts ms)          (Note  3) -        --              L  ( }:ts)  ms     = parse-error             (Note  3), matching of implicit/explicit braces is handled by parser+        -- L  ( }:ts)  ms     = parse-error             (Note  3), matching of implicit/explicit braces is handled by parser         -- L  ( {:ts)  ms     = {: (L  ts (0:ms))       (Note  4)          -- L  (t:ts)  (m:ms)  = }: (L  (t:ts)  ms)      if  m /= 0  and  parse-error(t) (Note  5)          -- L  (t:ts)  ms      = t : (L  ts ms) -        sameln tts ms = case splitStateE tts of+        sameln tts ms+          = case splitStateE tts of               Left'  t ts  ->                         let tail-                              | isTrigger t  = aftertrigger ts ms-                              | isClose t    = case ms of-                                                         0:rs -> layout ts rs-                                                         _    -> layout ts ms+                              | isTriggerGE t = aftertrigger True  ts ms+                              | isTriggerGT t = aftertrigger False ts ms+                              | isClose     t = case ms of+                                                  0:rs -> layout ts rs+                                                  _    -> layout ts ms -                              | isOpen t    = layout ts (0:ms)-                              | otherwise   = layout ts ms+                              | isOpen      t = layout ts (0:ms)+                              | otherwise     = layout ts ms                             parseError = case ms of                                            m:ms  | m /= 0 -> Just (layout tts ms)                                            _              -> Nothing                         in  Off pos (Cons (Symbol t) tail) parseError               Right' rest -> endofinput pos rest ms           where pos = getPosition tts-{--        sameln tts ms = case splitStateE tts of-                Left'  t ts  | isTrigger t -> cons pos (Symbol t) (aftertrigger ts ms)-                             | isClose t   -> cons pos (Symbol t) -                                                (case ms of-                                                   0:ms -> layout ts ms-                                                   _    -> layout ts ms-                                                )   -                             | isOpen t    -> cons pos (Symbol t) (layout ts (0:ms))                            -                             | otherwise   -> let parseError = case ms of-                                                                  m:ms  | m /= 0 -> Just (layout tts ms)-                                                                  _              -> Nothing-                                              in Off pos (Cons (Symbol t) (layout ts ms)) parseError-                Right' rest -> endofinput pos rest ms-          where pos = getPosition tts                        --}          -- L  []  []          = []          -- L  []  (m:ms)      = } : L  []  ms           if m /=0   (Note  6) @@ -116,18 +136,17 @@                                    | otherwise = endofinput pos rest ms  -data Stream inp s p = Cons (OffsideSymbol s) (OffsideInput inp s p) -                    | End inp--data OffsideInput inp s p = Off p (Stream inp s p) (Maybe (OffsideInput inp s p))- instance InputState inp s p => InputState (OffsideInput inp s p) (OffsideSymbol s) p where-  splitStateE inp@(Off p stream _) = case stream of-                                     Cons s rest -> Left' s rest-                                     _           -> Right' inp                                 -  splitState (Off _ stream _) = -           case stream of-            Cons s rest -> (# s ,rest #)                        +  splitStateE inp@(Off p stream _)+    = case stream of+        Cons s rest -> Left' s rest+                    where take 0 _                    = []+                          take _ (Off _ (End _)    _) = []+                          take n (Off _ (Cons h t) _) = h : take (n-1) t+        _           -> Right' inp                                 +  splitState (Off _ stream _)+    = case stream of+        Cons s rest -> (# s, rest #)    getPosition (Off pos _ _ ) = pos   @@ -140,7 +159,7 @@   symBefore s = case s of                  Symbol s   -> Symbol (symBefore s)                  SemiColon  -> error "Symbol.symBefore SemiColon"-                 OpenBrace  -> error "Symbol.symBeforeOpenBrace"+                 OpenBrace  -> error "Symbol.symBefore OpenBrace"                  CloseBrace -> error "Symbol.symBefore CloseBrace"   symAfter s = case s of                  Symbol s   -> Symbol (symAfter s)@@ -198,9 +217,12 @@ pClose = OP (pWrap f g ( () <$ pSym CloseBrace) )   where g state steps1 k = (state,ar,k)           where ar = case state of-                               Off _ _ (Just state') -> let steps2 = k state'-                                                        in if not (hasSuccess steps1) && hasSuccess steps2 then steps2 else steps1-                               _                     -> steps1+                               Off _ _ (Just state')+                                 -> let steps2 = k state'+                                    in if not (hasSuccess steps1) && hasSuccess steps2+                                       then Cost 1# steps2+                                       else steps1+                               _ -> steps1                      f acc state steps k = let (stl,ar,str2rr) = g state (val snd steps)  k                               in (stl ,val (acc ()) ar , str2rr )@@ -224,11 +246,18 @@        -> OffsideParser i o s p a         -> OffsideParser i o s p [a] pBlock open sep close p =  pOffside open close explicit implicit+ where elem = (Just <$> p) `opt` Nothing+       sep' = () <$ sep        +       elems s = (\h t -> catMaybes (h:t)) <$> elem <*> pList (s *> elem)+       explicit = elems sep'+       implicit = elems (sep' <|> pSeparator)+{-  where elem = (:) <$> p `opt` id        sep' = () <$ sep                elems s = ($[]) <$> pFoldr1Sep ((.),id) s elem        explicit = elems sep'        implicit = elems (sep' <|> pSeparator)+-}  pBlock1 :: (InputState i s p, OutputState o, Position p, Symbol s, Ord s)         => OffsideParser i o s p x @@ -237,11 +266,34 @@        -> OffsideParser i o s p a         -> OffsideParser i o s p [a] pBlock1 open sep close p =  pOffside open close explicit implicit+ where elem = (Just <$> p) `opt` Nothing+       sep' = () <$ sep+       elems s = (\h t -> catMaybes (h:t)) <$ pList s <*> (Just <$> p) <*> pList (s *> elem)+       explicit = elems sep'+       implicit = elems (sep' <|> pSeparator)+{-+ where elem = (Just <$> p) `opt` Nothing+       sep' = () <$ sep+       elems s = (\h t -> catMaybes (h:t)) <$ pList s <*> (Just <$> p) <*> pList ( s *> elem)+       explicit = elems sep'+       implicit = elems (sep' <|> pSeparator)+-}+{-+pBlock1 open sep close p =  pOffside open close explicit implicit+ where elem = (Just <$> p) <|> pSucceed Nothing+       sep' = () <$ sep+       elems s = (\h t -> catMaybes (h:t)) <$ pList s <*> (Just <$> p) <*> pList ( s *> elem)+       explicit = elems sep'+       implicit = elems (sep' <|> pSeparator)+-}+{-+pBlock1 open sep close p =  pOffside open close explicit implicit  where elem = (:) <$> p `opt` id        sep' = () <$ sep        elems s = (:) <$ pList s <*> p <*> (($[]) <$> pFoldr1Sep ((.),id) s elem)        explicit = elems sep'        implicit = elems (sep' <|> pSeparator)+-} {- pBlock1 open sep close p =  pOffside open close explicit implicit  where sep'    = () <$ sep
uulib.cabal view
@@ -1,7 +1,7 @@ cabal-version: >=1.1 build-type: Simple name: uulib-version: 0.9.10+version: 0.9.11 license: LGPL license-file: COPYRIGHT maintainer: Arie Middelkoop <ariem@cs.uu.nl>@@ -21,24 +21,21 @@   description: ghc-prim as separate module library   if flag(have_ghc_prim)-    build-depends: base>=4, ghc-prim+    build-depends: base>=4 && <10, ghc-prim   else     build-depends: base<4   build-depends: haskell98   exposed-modules: UU.Parsing.CharParser UU.Parsing.Derived                    UU.Parsing.Interface UU.Parsing.MachineInterface                    UU.Parsing.Merge UU.Parsing.Offside UU.Parsing.Perms-                   UU.Parsing.StateParser UU.Parsing UU.DData.IntBag -                   UU.DData.Map UU.DData.MultiSet UU.DData.Queue-                   UU.DData.Scc UU.DData.Seq UU.DData.Set UU.PPrint+                   UU.Parsing.StateParser UU.Parsing+                   UU.PPrint                    UU.Pretty.Ext UU.Pretty UU.Scanner.GenToken UU.Scanner.GenTokenOrd                    UU.Scanner.GenTokenParser UU.Scanner.GenTokenSymbol                    UU.Scanner.Position UU.Scanner.Scanner                    UU.Scanner.Token UU.Scanner.TokenParser UU.Scanner.TokenShow                    UU.Scanner UU.Util.BinaryTrees UU.Util.PermTree UU.Util.Utils                    UU.Pretty.Basic UU.Parsing.Machine    -                   UU.DData.IntMap  -                   UU.DData.IntSet           extensions:  RankNTypes FunctionalDependencies TypeSynonymInstances UndecidableInstances FlexibleInstances MultiParamTypeClasses FlexibleContexts CPP ExistentialQuantification   ghc-options: -fglasgow-exts   hs-source-dirs: src