--- Data-Set.hs_orig	2011-04-28 07:19:05.000000000 -0700
+++ Data-Set.hs	2011-04-28 07:20:30.000000000 -0700
@@ -73,6 +73,12 @@
             -- * Fold
             , fold
 
+            -- * Indexed
+            , lookupIndex
+            , findIndex
+            , elemAt
+            , deleteAt
+
             -- * Min\/Max
             , findMin
             , findMax
@@ -265,6 +271,78 @@
 
 
 {--------------------------------------------------------------------
+  Indexing
+--------------------------------------------------------------------}
+-- | /O(log n)/. Return the /index/ of an element. The index is a
+-- number from /0/ up to, but not including, the 'size' of the
+-- set. Calls 'error' when the element is not a 'member' of the map.
+--
+-- > findIndex 2 (fromList [5, 3])    Error: element is not in the set
+-- > findIndex 3 (fromList [5, 3]) == 0
+-- > findIndex 5 (fromList [5, 3]) == 1
+-- > findIndex 6 (fromList [5, 3])    Error: element is not in the set
+
+findIndex :: Ord a => a -> Set a -> Int
+findIndex k t
+  = case lookupIndex k t of
+      Nothing  -> error "Set.findIndex: element is not in the set"
+      Just idx -> idx
+
+-- | /O(log n)/. Lookup the /index/ of an element. The index is a
+-- number from /0/ up to, but not including, the 'size' of the set.
+--
+-- > isJust (lookupIndex 2 (fromList [5, 3]))   == False
+-- > fromJust (lookupIndex 3 (fromList [5, 3])) == 0
+-- > fromJust (lookupIndex 5 (fromList [5, 3])) == 1
+-- > isJust (lookupIndex 6 (fromList [5, 3]))   == False
+
+lookupIndex :: Ord a => a -> Set a -> Maybe Int
+lookupIndex k = k `seq` go 0
+  where
+    go idx Tip  = idx `seq` Nothing
+    go idx (Bin _ kx l r)
+      = idx `seq` case compare k kx of
+          LT -> go idx l
+          GT -> go (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 0 (fromList [5, 3]) == (3,"b")
+-- > elemAt 1 (fromList [5, 3]) == (5, "a")
+-- > elemAt 2 (fromList [5, 3])    Error: index out of range
+
+elemAt :: Int -> Set a -> a
+elemAt _ Tip = error "Set.elemAt: index out of range"
+elemAt i (Bin _ kx l r)
+  = case compare i sizeL of
+      LT -> elemAt i l
+      GT -> elemAt (i-sizeL-1) r
+      EQ -> kx
+  where
+    sizeL = size l
+
+-- | /O(log n)/. Delete the element at /index/.
+--
+-- > deleteAt 0  (fromList [5, 3]) == singleton 5
+-- > deleteAt 1  (fromList [5, 3]) == singleton 3
+-- > deleteAt 2 (fromList [5, 3])     Error: index out of range
+-- > deleteAt (-1) (fromList [5, 3])  Error: index out of range
+
+deleteAt :: Int -> Set a -> Set a
+deleteAt i0 t = i0 `seq` go i0 t
+ where
+    go _ Tip = error "Set.deleteAt: index out of range"
+    go i (Bin sx kx l r) = case compare i sizeL of
+      LT -> balance kx (go i l) r
+      GT -> balance kx l (go (i-sizeL-1) r)
+      EQ -> glue l r
+      where 
+        sizeL = size l
+
+
+{--------------------------------------------------------------------
   Minimal, Maximal
 --------------------------------------------------------------------}
 -- | /O(log n)/. The minimal element of a set.
