Safe Haskell | Safe |
---|---|
Language | Haskell98 |
Simple but efficient strict sequence type based on a nested data type and polymorphic recursion.
It is like a list, but instead of O(1)
cons/uncons and O(k)
lookup,
we have amortized O(1)
cons/uncons and O(log(k))
lookup (both are O(log(n))
in the worst case).
This is somewhat similar to a finger tree (which is also represented by a nested data type), but
much simpler and more memory efficient (memory usage is basically the same as with lists: amortized
3 words per element, plus the data itself).
However, modifying the right end of the sequence is still slow: O(n)
. This affects the functions
snoc
, unSnoc
, append
, take
, init
. Somewhat surprisingly, extracting the last element is
still fast.
An example usage is a pure random-access stack.
This module is intended to be imported qualified.
- data Seq a
- cons :: a -> Seq a -> Seq a
- unCons :: Seq a -> Maybe (a, Seq a)
- null :: Seq a -> Bool
- length :: Seq a -> Int
- empty :: Seq a
- toList :: Seq a -> [a]
- fromList :: [a] -> Seq a
- singleton :: a -> Seq a
- pair :: a -> a -> Seq a
- triple :: a -> a -> a -> Seq a
- quad :: a -> a -> a -> a -> Seq a
- head :: Seq a -> a
- tail :: Seq a -> Seq a
- last :: Seq a -> a
- mbHead :: Seq a -> Maybe a
- mbTail :: Seq a -> Maybe (Seq a)
- tails :: Seq a -> [Seq a]
- mbLast :: Seq a -> Maybe a
- lookup :: Int -> Seq a -> a
- mbLookup :: Int -> Seq a -> Maybe a
- update :: (a -> a) -> Int -> Seq a -> Seq a
- replace :: Int -> a -> Seq a -> Seq a
- drop :: Int -> Seq a -> Seq a
- append :: Seq a -> Seq a -> Seq a
- take :: Int -> Seq a -> Seq a
- init :: Seq a -> Seq a
- mbInit :: Seq a -> Maybe (Seq a)
- snoc :: Seq a -> a -> Seq a
- unSnoc :: Seq a -> Maybe (Seq a, a)
- toListNaive :: Seq a -> [a]
- checkInvariant :: Seq a -> Bool
- showInternal :: Show a => Seq a -> String
- graphviz :: Show a => Seq a -> String
Documentation
The strict sequence type. See Data.Nested.Seq.Lazy for more detailed information.
Accessing the left end of the sequence
Basic queries
Basic construction
Short sequences
Unsafe head and tail
Safe head and tail
mbHead :: Seq a -> Maybe a Source
First element of the sequence. Worst case O(log(n))
, amortized O(1)
.
Indexing
lookup :: Int -> Seq a -> a Source
Lookup the k
-th element of a sequence. This is worst case O(log(n))
and amortized O(log(k))
, and quite efficient.
replace :: Int -> a -> Seq a -> Seq a Source
Replace the k
-th element. replace n x == update (const x) n
drop :: Int -> Seq a -> Seq a Source
Drop is efficient: drop k
is amortized O(log(k))
, worst case maybe O(log(n)^2)
?
Slow operations
append :: Seq a -> Seq a -> Seq a Source
O(n)
(for large n
at least), where n
is the length of the first sequence.
mbInit :: Seq a -> Maybe (Seq a) Source
The sequence without the last element. Warning, this is slow, O(n)
unSnoc :: Seq a -> Maybe (Seq a, a) Source
Stripping the last element from a sequence is a slow operation, O(n)
.
If you only need extracting the last element, use mbLast
instead,
which is fast.
Debugging
toListNaive :: Seq a -> [a] Source
Naive implementation of toList
checkInvariant :: Seq a -> Bool Source
We maintain the invariant that (Z Nil)
never appears. This function
checks whether this is satisfied. Used only for testing.
showInternal :: Show a => Seq a -> String Source
Show the internal structure of the sequence. The constructor names
Z
and O
come from "zero" and "one", respectively.