Safe Haskell | Safe |
---|---|
Language | Haskell2010 |
This module provides alternating finger trees, based on
Seq
from the containers
package. Between every element
(of type e
) in the 'normal' finger tree, there is a
'separator' of type a
.
is isomorphic to
TwoFingerOddA
e ()[e]
, and
is isomorphic to TwoFingerOddA
e a([(a, e)], a)
.
(The type variables are in that order because that permits a
Traversable1
instance for TwoFingerOddA
.)
Four flavours of alternating finger trees are present, corresponding to different element patterns:
, which is likeTwoFingerOddA
e aa (e a)*
.
, which is likeTwoFingerOddE
e ae (a e)*
.
, which is likeTwoFingerEvenA
e a(a e)*
.
, which is likeTwoFingerEvenE
e a(e a)*
.
The flavours' names first describe whether they have the same
number of a
s and e
s within them (the Even
flavours do, the
Odd
ones do not), and then whether the first element is an e
or
an a
.
(Full) conses and snocs prepend or append a pair of elements to the front or rear of an alternating finger tree, keeping the flavour the same. Half-conses and -snocs transform between these flavours, adding only half the pair. All cons-like operations have an inverse operation. Some half-conses and -snocs and their inverses are \(O(1)\) amortised, with \(O(\log n)\) worst case, while some are \(O(1)\) always. All full conses, snocs and inverses are \(O(1)\) amortised and \(O(\log n)\) worst case.
Note that the names of half-conses and -snocs take the flavour that
they operate on, which means that, for example, halfconsOddA
and
halfunconsOddA
are not inverses; the actual inverse pairs are
halfconsOddA
+ halfunconsEvenE
and halfconsEvenE
+
halfunconsOddA
.
Appending alternating finger trees is also efficient. As well as
the usual Monoid
and Semigroup
instances, the two Even
flavours can be viewed as monoid actions of the Odd
flavours. All
append-like operations are \(O(\log(\min(n, m)))\) amortised and
\(O(\log(\max(n, m)))\) worst case.
For more information on finger trees, see:
- Ralf Hinze and Ross Paterson, "Finger trees: a simple general-purpose data structure", Journal of Functional Programming 16:2 (2006) pp 197-217. http://staff.city.ac.uk/~ross/papers/FingerTree.html
Many of the functions in this package follow laws, which are not documented inline. tests/Properties.hs is an automatically-tested QuickCheck suite of properties.
- data TwoFingerOddA e a
- singletonOddA :: a -> TwoFingerOddA e a
- unitOddA :: (Monoid a, Semigroup a) => e -> TwoFingerOddA e a
- onlyOddA :: TwoFingerOddA e a -> Maybe a
- interleavingOddA :: e -> NonEmpty a -> TwoFingerOddA e a
- consOddA :: a -> e -> TwoFingerOddA e a -> TwoFingerOddA e a
- unconsOddA :: TwoFingerOddA e a -> Either a ((a, e), TwoFingerOddA e a)
- snocOddA :: TwoFingerOddA e a -> e -> a -> TwoFingerOddA e a
- unsnocOddA :: TwoFingerOddA e a -> Either a (TwoFingerOddA e a, (e, a))
- halfconsOddA :: e -> TwoFingerOddA e a -> TwoFingerEvenE e a
- halfunconsOddA :: TwoFingerOddA e a -> (a, TwoFingerEvenE e a)
- halfsnocOddA :: TwoFingerOddA e a -> e -> TwoFingerEvenA e a
- halfunsnocOddA :: TwoFingerOddA e a -> (TwoFingerEvenA e a, a)
- firstOddA :: Functor f => (a -> f a) -> TwoFingerOddA e a -> f (TwoFingerOddA e a)
- lastOddA :: Functor f => (a -> f a) -> TwoFingerOddA e a -> f (TwoFingerOddA e a)
- data TwoFingerOddE e a
- singletonOddE :: e -> TwoFingerOddE e a
- consOddE :: e -> a -> TwoFingerOddE e a -> TwoFingerOddE e a
- snocOddE :: TwoFingerOddE e a -> a -> e -> TwoFingerOddE e a
- unconsOddE :: TwoFingerOddE e a -> Either e ((e, a), TwoFingerOddE e a)
- unsnocOddE :: TwoFingerOddE e a -> Either e (TwoFingerOddE e a, (a, e))
- halfconsOddE :: a -> TwoFingerOddE e a -> TwoFingerEvenA e a
- halfsnocOddE :: TwoFingerOddE e a -> a -> TwoFingerEvenE e a
- halfunconsOddE :: TwoFingerOddE e a -> (e, TwoFingerEvenA e a)
- halfunsnocOddE :: TwoFingerOddE e a -> (TwoFingerEvenE e a, e)
- data TwoFingerEvenA e a
- consEvenA :: a -> e -> TwoFingerEvenA e a -> TwoFingerEvenA e a
- unconsEvenA :: TwoFingerEvenA e a -> Maybe ((a, e), TwoFingerEvenA e a)
- snocEvenA :: TwoFingerEvenA e a -> a -> e -> TwoFingerEvenA e a
- unsnocEvenA :: TwoFingerEvenA e a -> Maybe (TwoFingerEvenA e a, (a, e))
- halfconsEvenA :: e -> TwoFingerEvenA e a -> TwoFingerOddE e a
- halfsnocEvenA :: TwoFingerEvenA e a -> a -> TwoFingerOddA e a
- halfunconsEvenA :: TwoFingerEvenA e a -> Maybe (a, TwoFingerOddE e a)
- halfunsnocEvenA :: TwoFingerEvenA e a -> Maybe (TwoFingerOddA e a, e)
- data TwoFingerEvenE e a
- consEvenE :: e -> a -> TwoFingerEvenE e a -> TwoFingerEvenE e a
- unconsEvenE :: TwoFingerEvenE e a -> Maybe ((e, a), TwoFingerEvenE e a)
- snocEvenE :: TwoFingerEvenE e a -> e -> a -> TwoFingerEvenE e a
- unsnocEvenE :: TwoFingerEvenE e a -> Maybe (TwoFingerEvenE e a, (e, a))
- halfconsEvenE :: a -> TwoFingerEvenE e a -> TwoFingerOddA e a
- halfsnocEvenE :: TwoFingerEvenE e a -> e -> TwoFingerOddE e a
- halfunconsEvenE :: TwoFingerEvenE e a -> Maybe (e, TwoFingerOddA e a)
- halfunsnocEvenE :: TwoFingerEvenE e a -> Maybe (TwoFingerOddE e a, a)
- appendEvenAOddA :: TwoFingerEvenA e a -> TwoFingerOddA e a -> TwoFingerOddA e a
- appendOddEEvenA :: TwoFingerOddE e a -> TwoFingerEvenA e a -> TwoFingerOddE e a
- appendOddAEvenE :: TwoFingerOddA e a -> TwoFingerEvenE e a -> TwoFingerOddA e a
- appendEvenEOddE :: TwoFingerEvenE e a -> TwoFingerOddE e a -> TwoFingerOddE e a
- appendOddAOddE :: TwoFingerOddA e a -> TwoFingerOddE e a -> TwoFingerEvenA e a
- appendOddEOddA :: TwoFingerOddE e a -> TwoFingerOddA e a -> TwoFingerEvenE e a
TwoFingerOddA
data TwoFingerOddA e a Source #
Isomorphic to a, (e, a)*
Construction and analysis
singletonOddA :: a -> TwoFingerOddA e a Source #
unitOddA :: (Monoid a, Semigroup a) => e -> TwoFingerOddA e a Source #
Surrounds the argument with mempty
.
>>>
unitOddA 3 :: TwoFingerOddA Int String
consOddA "" 3 (singletonOddA "")
onlyOddA :: TwoFingerOddA e a -> Maybe a Source #
>>>
onlyOddA (singletonOddA "Hello!")
Just "Hello!">>>
onlyOddA (consOddA True 3 $ singletonOddA False)
Nothing
interleavingOddA :: e -> NonEmpty a -> TwoFingerOddA e a Source #
>>>
interleavingOddA "sep" (3 :| [4, 5])
consOddA 3 "sep" (consOddA 4 "sep" (singletonOddA 5))
Full conses
consOddA :: a -> e -> TwoFingerOddA e a -> TwoFingerOddA e a Source #
unconsOddA :: TwoFingerOddA e a -> Either a ((a, e), TwoFingerOddA e a) Source #
snocOddA :: TwoFingerOddA e a -> e -> a -> TwoFingerOddA e a Source #
unsnocOddA :: TwoFingerOddA e a -> Either a (TwoFingerOddA e a, (e, a)) Source #
Half conses
halfconsOddA :: e -> TwoFingerOddA e a -> TwoFingerEvenE e a Source #
\(O(1)\) worst case. Inverse: halfunconsEvenE
halfunconsOddA :: TwoFingerOddA e a -> (a, TwoFingerEvenE e a) Source #
\(O(\log n)\) worst case. Inverse: halfconsEvenE
halfsnocOddA :: TwoFingerOddA e a -> e -> TwoFingerEvenA e a Source #
\(O(\log n)\) worst case. Inverse: halfunsnocEvenA
halfunsnocOddA :: TwoFingerOddA e a -> (TwoFingerEvenA e a, a) Source #
\(O(1)\) worst case. Inverse: halfsnocEvenA
Lenses
firstOddA :: Functor f => (a -> f a) -> TwoFingerOddA e a -> f (TwoFingerOddA e a) Source #
Access the first a
of a
. \(O(1)\). This
type is TwoFingerOddA
e aLens' (
in disguise.TwoFingerOddA
e a) a
>>>
view firstOddA (consOddA 3 True $ singletonOddA 15)
3
lastOddA :: Functor f => (a -> f a) -> TwoFingerOddA e a -> f (TwoFingerOddA e a) Source #
Access the last a
of a
. \(O(1)\). This type
is TwoFingerOddA
e aLens' (
in disguise.TwoFingerOddA
e a) a
>>>
over lastOddA (+ 5) (consOddA 3 True $ singletonOddA 15)
consOddA 3 True (singletonOddA 20)
TwoFingerOddE
data TwoFingerOddE e a Source #
Isomorphic to e, (a, e)*
Bitraversable TwoFingerOddE Source # | |
Bifoldable TwoFingerOddE Source # | |
Bifunctor TwoFingerOddE Source # | |
Eq2 TwoFingerOddE Source # | |
Show2 TwoFingerOddE Source # | |
Bitraversable1 TwoFingerOddE Source # | |
Bifoldable1 TwoFingerOddE Source # | |
Functor (TwoFingerOddE e) Source # | |
Foldable (TwoFingerOddE e) Source # | |
Traversable (TwoFingerOddE e) Source # | |
Eq e => Eq1 (TwoFingerOddE e) Source # | |
Show e => Show1 (TwoFingerOddE e) Source # | |
(Eq e, Eq a) => Eq (TwoFingerOddE e a) Source # | |
(Show e, Show a) => Show (TwoFingerOddE e a) Source # | |
Generic (TwoFingerOddE e a) Source # | |
(NFData e, NFData a) => NFData (TwoFingerOddE e a) Source # | |
type Rep (TwoFingerOddE e a) Source # | |
Construction
singletonOddE :: e -> TwoFingerOddE e a Source #
Full conses
consOddE :: e -> a -> TwoFingerOddE e a -> TwoFingerOddE e a Source #
snocOddE :: TwoFingerOddE e a -> a -> e -> TwoFingerOddE e a Source #
unconsOddE :: TwoFingerOddE e a -> Either e ((e, a), TwoFingerOddE e a) Source #
unsnocOddE :: TwoFingerOddE e a -> Either e (TwoFingerOddE e a, (a, e)) Source #
Half conses
halfconsOddE :: a -> TwoFingerOddE e a -> TwoFingerEvenA e a Source #
\(O(\log n)\) worst case. Inverse: halfunconsEvenA
halfsnocOddE :: TwoFingerOddE e a -> a -> TwoFingerEvenE e a Source #
\(O(1)\) worst case. Inverse: halfunsnocEvenE
halfunconsOddE :: TwoFingerOddE e a -> (e, TwoFingerEvenA e a) Source #
\(O(1)\) worst case. Inverse: halfconsEvenA
halfunsnocOddE :: TwoFingerOddE e a -> (TwoFingerEvenE e a, e) Source #
\(O(\log n)\) worst case. Inverse: halfsnocEvenE
TwoFingerEvenA
data TwoFingerEvenA e a Source #
Isomorphic to (a, e)*
Bitraversable TwoFingerEvenA Source # | |
Bifoldable TwoFingerEvenA Source # | |
Bifunctor TwoFingerEvenA Source # | |
Eq2 TwoFingerEvenA Source # | |
Show2 TwoFingerEvenA Source # | |
Functor (TwoFingerEvenA e) Source # | |
Foldable (TwoFingerEvenA e) Source # | |
Traversable (TwoFingerEvenA e) Source # | |
Eq e => Eq1 (TwoFingerEvenA e) Source # | |
Show e => Show1 (TwoFingerEvenA e) Source # | |
Plus (TwoFingerEvenA e) Source # | |
Alt (TwoFingerEvenA e) Source # | |
(Eq e, Eq a) => Eq (TwoFingerEvenA e a) Source # | |
(Show e, Show a) => Show (TwoFingerEvenA e a) Source # | |
Generic (TwoFingerEvenA e a) Source # | |
Semigroup (TwoFingerEvenA e a) Source # | |
Monoid (TwoFingerEvenA e a) Source # | |
(NFData e, NFData a) => NFData (TwoFingerEvenA e a) Source # | |
type Rep (TwoFingerEvenA e a) Source # | |
Full conses
consEvenA :: a -> e -> TwoFingerEvenA e a -> TwoFingerEvenA e a Source #
unconsEvenA :: TwoFingerEvenA e a -> Maybe ((a, e), TwoFingerEvenA e a) Source #
snocEvenA :: TwoFingerEvenA e a -> a -> e -> TwoFingerEvenA e a Source #
unsnocEvenA :: TwoFingerEvenA e a -> Maybe (TwoFingerEvenA e a, (a, e)) Source #
Half conses
halfconsEvenA :: e -> TwoFingerEvenA e a -> TwoFingerOddE e a Source #
\(O(1)\) worst case. Inverse: halfunconsOddE
.
halfsnocEvenA :: TwoFingerEvenA e a -> a -> TwoFingerOddA e a Source #
\(O(1)\) worst case. Inverse: halfunsnocOddA
.
halfunconsEvenA :: TwoFingerEvenA e a -> Maybe (a, TwoFingerOddE e a) Source #
\(O(\log n)\) worst case. Inverse: halfconsOddE
.
halfunsnocEvenA :: TwoFingerEvenA e a -> Maybe (TwoFingerOddA e a, e) Source #
\(O(\log n)\) worst case. Inverse: halfsnocOddA
.
TwoFingerEvenE
data TwoFingerEvenE e a Source #
Isomorphic to (e, a)*
Bitraversable TwoFingerEvenE Source # | |
Bifoldable TwoFingerEvenE Source # | |
Bifunctor TwoFingerEvenE Source # | |
Eq2 TwoFingerEvenE Source # | |
Show2 TwoFingerEvenE Source # | |
Functor (TwoFingerEvenE e) Source # | |
Foldable (TwoFingerEvenE e) Source # | |
Traversable (TwoFingerEvenE e) Source # | |
Eq e => Eq1 (TwoFingerEvenE e) Source # | |
Show e => Show1 (TwoFingerEvenE e) Source # | |
Plus (TwoFingerEvenE e) Source # | |
Alt (TwoFingerEvenE e) Source # | |
(Eq e, Eq a) => Eq (TwoFingerEvenE e a) Source # | |
(Show e, Show a) => Show (TwoFingerEvenE e a) Source # | |
Generic (TwoFingerEvenE e a) Source # | |
Semigroup (TwoFingerEvenE e a) Source # | |
Monoid (TwoFingerEvenE e a) Source # | |
(NFData e, NFData a) => NFData (TwoFingerEvenE e a) Source # | |
type Rep (TwoFingerEvenE e a) Source # | |
Full conses
consEvenE :: e -> a -> TwoFingerEvenE e a -> TwoFingerEvenE e a Source #
unconsEvenE :: TwoFingerEvenE e a -> Maybe ((e, a), TwoFingerEvenE e a) Source #
snocEvenE :: TwoFingerEvenE e a -> e -> a -> TwoFingerEvenE e a Source #
unsnocEvenE :: TwoFingerEvenE e a -> Maybe (TwoFingerEvenE e a, (e, a)) Source #
Half conses
halfconsEvenE :: a -> TwoFingerEvenE e a -> TwoFingerOddA e a Source #
\(O(\log n)\) worst case. Inverse: halfunconsOddA
halfsnocEvenE :: TwoFingerEvenE e a -> e -> TwoFingerOddE e a Source #
\(O(\log n)\) worst case. Inverse: halfunsnocOddE
.
halfunconsEvenE :: TwoFingerEvenE e a -> Maybe (e, TwoFingerOddA e a) Source #
\(O(1)\) worst case. Inverse: halfconsOddA
.
halfunsnocEvenE :: TwoFingerEvenE e a -> Maybe (TwoFingerOddE e a, a) Source #
\(O(1)\) worst case. Inverse: halfsnocOddE
.
Appending different flavours
Monoid actions
appendEvenAOddA :: TwoFingerEvenA e a -> TwoFingerOddA e a -> TwoFingerOddA e a Source #
appendOddEEvenA :: TwoFingerOddE e a -> TwoFingerEvenA e a -> TwoFingerOddE e a Source #
appendOddAEvenE :: TwoFingerOddA e a -> TwoFingerEvenE e a -> TwoFingerOddA e a Source #
appendEvenEOddE :: TwoFingerEvenE e a -> TwoFingerOddE e a -> TwoFingerOddE e a Source #
Two odds make an even
appendOddAOddE :: TwoFingerOddA e a -> TwoFingerOddE e a -> TwoFingerEvenA e a Source #
appendOddEOddA :: TwoFingerOddE e a -> TwoFingerOddA e a -> TwoFingerEvenE e a Source #