Safe Haskell | Safe |
---|---|
Language | Haskell2010 |
This module provides alternating finger trees, which are similar
to Data.Sequence in the containers
package, or
Data.FingerTree in the fingertree
package, except that, 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
This package's alternating finger trees are not annotated with sizes as described in section 4 of the paper.
- 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
- alignLeftOddAOddA :: TwoFingerOddA e a -> TwoFingerOddA e' a' -> (TwoFingerOddA (e, e') (a, a'), Either (TwoFingerEvenE e a) (TwoFingerEvenE e' a'))
- alignLeftOddAEvenA :: TwoFingerOddA e a -> TwoFingerEvenA e' a' -> Either (TwoFingerEvenA (e, e') (a, a'), TwoFingerOddA e a) (TwoFingerOddA (e, e') (a, a'), TwoFingerOddE e' a')
- alignLeftOddEOddE :: TwoFingerOddE e a -> TwoFingerOddE e' a' -> (TwoFingerOddE (e, e') (a, a'), Either (TwoFingerEvenA e a) (TwoFingerEvenA e' a'))
- alignLeftOddEEvenE :: TwoFingerOddE e a -> TwoFingerEvenE e' a' -> Either (TwoFingerEvenE (e, e') (a, a'), TwoFingerOddE e a) (TwoFingerOddE (e, e') (a, a'), TwoFingerOddA e' a')
- repeatOddA :: a -> e -> TwoFingerOddA e a
- repeatOddE :: e -> a -> TwoFingerOddE e a
- repeatEvenA :: a -> e -> TwoFingerEvenA e a
- repeatEvenE :: e -> a -> TwoFingerEvenE e a
- infiniteOddA :: Stream a -> Stream e -> Stream e -> Stream a -> TwoFingerOddA e a
- infiniteOddE :: Stream e -> Stream a -> Stream a -> Stream e -> TwoFingerOddE e a
- infiniteEvenA :: Stream a -> Stream e -> Stream a -> Stream e -> TwoFingerEvenA e a
- infiniteEvenE :: Stream e -> Stream a -> Stream e -> Stream 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(\log n)\) worst case. Inverse: halfunconsEvenE
\e (AnyOddA as) -> halfunconsEvenE (halfconsOddA e as) == Just (e, as)
halfunconsOddA :: TwoFingerOddA e a -> (a, TwoFingerEvenE e a) Source #
\(O(1)\) worst case. Inverse: halfconsEvenE
\(AnyOddA as) -> as == uncurry halfconsEvenE (halfunconsOddA as)
halfsnocOddA :: TwoFingerOddA e a -> e -> TwoFingerEvenA e a Source #
\(O(\log n)\) worst case. Inverse: halfunsnocEvenA
\(AnyOddA as) e -> halfunsnocEvenA (halfsnocOddA as e) == Just (as, e)
halfunsnocOddA :: TwoFingerOddA e a -> (TwoFingerEvenA e a, a) Source #
\(O(1)\) worst case. Inverse: halfsnocOddA
\(AnyOddA as) -> as == uncurry halfsnocEvenA (halfunsnocOddA as)
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)*
Eq2 TwoFingerOddE Source # | |
Show2 TwoFingerOddE Source # | |
Bifunctor TwoFingerOddE Source # | |
Bitraversable TwoFingerOddE Source # | |
Bifoldable 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(1)\) worst case. Inverse: halfunconsEvenA
\a (AnyOddE as) -> halfunconsEvenA (halfconsOddE a as) == Just (a, as)
halfsnocOddE :: TwoFingerOddE e a -> a -> TwoFingerEvenE e a Source #
\(O(1)\) worst case. Inverse: halfunsnocEvenE
\(AnyOddE as) a -> halfunsnocEvenE (halfsnocOddE as a) == Just (as, a)
halfunconsOddE :: TwoFingerOddE e a -> (e, TwoFingerEvenA e a) Source #
\(O(\log n)\) worst case. Inverse: halfconsEvenA
\(AnyOddE as) -> as == uncurry halfconsEvenA (halfunconsOddE as)
halfunsnocOddE :: TwoFingerOddE e a -> (TwoFingerEvenE e a, e) Source #
\(O(\log n)\) worst case. Inverse: halfsnocEvenE
\(AnyOddE as) -> as == uncurry halfsnocEvenE (halfunsnocOddE as)
TwoFingerEvenA
data TwoFingerEvenA e a Source #
Isomorphic to (a, e)*
Eq2 TwoFingerEvenA Source # | |
Show2 TwoFingerEvenA Source # | |
Bifunctor TwoFingerEvenA Source # | |
Bitraversable TwoFingerEvenA Source # | |
Bifoldable 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 # | \(AnyEvenA a) (AnyEvenA b) (AnyEvenA c) -> (a <> b) <> c == a <> (b <> c) |
Monoid (TwoFingerEvenA e a) Source # | \(AnyEvenA a) -> a == a <> mempty \(AnyEvenA a) -> a == mempty <> a |
(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(\log n)\) worst case. Inverse: halfunconsOddE
.
\e (AnyEvenA as) -> halfunconsOddE (halfconsEvenA e as) == (e, as)
halfsnocEvenA :: TwoFingerEvenA e a -> a -> TwoFingerOddA e a Source #
\(O(1)\) worst case. Inverse: halfunsnocOddA
.
\(AnyEvenA as) a -> halfunsnocOddA (halfsnocEvenA as a) == (as, a)
halfunconsEvenA :: TwoFingerEvenA e a -> Maybe (a, TwoFingerOddE e a) Source #
\(O(1)\) worst case. Inverse: halfconsOddE
.
\(AnyEvenA as) -> as == maybe mempty (uncurry halfconsOddE) (halfunconsEvenA as)
halfunsnocEvenA :: TwoFingerEvenA e a -> Maybe (TwoFingerOddA e a, e) Source #
\(O(\log n)\) worst case. Inverse: halfsnocOddA
.
\(AnyEvenA as) -> as == maybe mempty (uncurry halfsnocOddA) (halfunsnocEvenA as)
TwoFingerEvenE
data TwoFingerEvenE e a Source #
Isomorphic to (e, a)*
Eq2 TwoFingerEvenE Source # | |
Show2 TwoFingerEvenE Source # | |
Bifunctor TwoFingerEvenE Source # | |
Bitraversable TwoFingerEvenE Source # | |
Bifoldable 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 # | \(AnyEvenE a) (AnyEvenE b) (AnyEvenE c) -> (a <> b) <> c == a <> (b <> c) |
Monoid (TwoFingerEvenE e a) Source # | \(AnyEvenE a) -> a == a <> mempty \(AnyEvenE a) -> a == mempty <> a |
(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(1)\) worst case. Inverse: halfunconsOddA
\a (AnyEvenE as) -> halfunconsOddA (halfconsEvenE a as) == (a, as)
halfsnocEvenE :: TwoFingerEvenE e a -> e -> TwoFingerOddE e a Source #
\(O(\log n)\) worst case. Inverse: halfunsnocOddE
.
\(AnyEvenE as) e -> halfunsnocOddE (halfsnocEvenE as e) == (as, e)
halfunconsEvenE :: TwoFingerEvenE e a -> Maybe (e, TwoFingerOddA e a) Source #
\(O(\log n)\) worst case. Inverse: halfconsOddA
.
\(AnyEvenE as) -> as == maybe mempty (uncurry halfconsOddA) (halfunconsEvenE as)
halfunsnocEvenE :: TwoFingerEvenE e a -> Maybe (TwoFingerOddE e a, a) Source #
\(O(1)\) worst case. Inverse: halfsnocOddE
.
\(AnyEvenE as) -> as == maybe mempty (uncurry halfsnocOddE) (halfunsnocEvenE as)
Appending different flavours
\(AnyOddA a) (AnyOddA b) (AnyEvenE c) -> appendOddAEvenE (a <> b) c == a <> appendOddAEvenE b c
\(AnyOddA a) (AnyOddE b) (AnyOddA c) -> appendEvenAOddA (appendOddAOddE a b) c == appendOddAEvenE a (appendOddEOddA b c)
\(AnyOddA a) (AnyOddE b) (AnyEvenA c) -> appendOddAOddE a (appendOddEEvenA b c) == appendOddAOddE a b <> c
\(AnyOddA a) (AnyEvenE b) (AnyOddE c) -> appendOddAOddE a (appendEvenEOddE b c) == appendOddAOddE (appendOddAEvenE a b) c
\(AnyOddA a) (AnyEvenE b) (AnyEvenE c) -> appendOddAEvenE a (b <> c) == appendOddAEvenE (appendOddAEvenE a b) c
\(AnyOddE a) (AnyOddA b) (AnyOddE c) -> appendOddEEvenA a (appendOddAOddE b c) == appendEvenEOddE (appendOddEOddA a b) c
\(AnyOddE a) (AnyOddA b) (AnyEvenE c) -> appendOddEOddA a (appendOddAEvenE b c) == appendOddEOddA a b <> c
\(AnyOddE a) (AnyEvenA b) (AnyOddA c) -> appendOddEOddA a (appendEvenAOddA b c) == appendOddEOddA (appendOddEEvenA a b) c
\(AnyOddE a) (AnyEvenA b) (AnyEvenA c) -> appendOddEEvenA a (b <> c) == appendOddEEvenA (appendOddEEvenA a b) c
\(AnyEvenA a) (AnyOddA b) (AnyOddA c) -> appendEvenAOddA a (b <> c) == appendEvenAOddA a b <> c
\(AnyEvenA a) (AnyOddA b) (AnyOddE c) -> appendOddAOddE (appendEvenAOddA a b) c == a <> appendOddAOddE b c
\(AnyEvenA a) (AnyOddA b) (AnyEvenE c) -> appendOddAEvenE (appendEvenAOddA a b) c == appendEvenAOddA a (appendOddAEvenE b c)
\(AnyEvenA a) (AnyEvenA b) (AnyOddA c) -> appendEvenAOddA (a <> b) c == appendEvenAOddA a (appendEvenAOddA b c)
\(AnyEvenE a) (AnyOddE b) (AnyOddA c) -> appendOddEOddA (appendEvenEOddE a b) c == a <> appendOddEOddA b c
\(AnyEvenE a) (AnyOddE b) (AnyEvenA c) -> appendOddEEvenA (appendEvenEOddE a b) c == appendEvenEOddE a (appendOddEEvenA b c)
\(AnyEvenE a) (AnyEvenE b) (AnyOddE c) -> appendEvenEOddE (a <> b) c == appendEvenEOddE a (appendEvenEOddE b c)
appendEvenAOddA :: TwoFingerEvenA e a -> TwoFingerOddA e a -> TwoFingerOddA e a Source #
\(AnyOddA a) -> a == appendEvenAOddA mempty a
appendOddEEvenA :: TwoFingerOddE e a -> TwoFingerEvenA e a -> TwoFingerOddE e a Source #
\(AnyOddE a) -> a == appendOddEEvenA a mempty
appendOddAEvenE :: TwoFingerOddA e a -> TwoFingerEvenE e a -> TwoFingerOddA e a Source #
\(AnyOddA a) -> a == appendOddAEvenE a mempty
appendEvenEOddE :: TwoFingerEvenE e a -> TwoFingerOddE e a -> TwoFingerOddE e a Source #
\(AnyOddE a) -> a == appendEvenEOddE mempty a
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 #
Aligning (zipping)
alignLeftOddAOddA :: TwoFingerOddA e a -> TwoFingerOddA e' a' -> (TwoFingerOddA (e, e') (a, a'), Either (TwoFingerEvenE e a) (TwoFingerEvenE e' a')) Source #
Align two TwoFingerOddA
sequences elementwise, and return the excess remainder.
>>>
alignLeftOddAOddA (consOddA 'a' 1 $ consOddA 'b' 2 $ singletonOddA 'c') (consOddA "foo" 10 $ singletonOddA "bar")
(consOddA ('a',"foo") (1,10) (singletonOddA ('b',"bar")),Left (consEvenE 2 'c' mempty))
>>>
alignLeftOddAOddA (consOddA 'a' 1 $ singletonOddA 'b') (consOddA "foo" 10 $ consOddA "bar" 20 $ singletonOddA "baz")
(consOddA ('a',"foo") (1,10) (singletonOddA ('b',"bar")),Right (consEvenE 20 "baz" mempty))
\(AnyOddA as) (AnyOddA bs) -> let { (aligned, rest) = alignLeftOddAOddA as bs ; as' = appendOddAEvenE (bimap fst fst aligned) (either id (const mempty) rest) ; bs' = appendOddAEvenE (bimap snd snd aligned) (either (const mempty) id rest) } in as == as' && bs == bs'
alignLeftOddAEvenA :: TwoFingerOddA e a -> TwoFingerEvenA e' a' -> Either (TwoFingerEvenA (e, e') (a, a'), TwoFingerOddA e a) (TwoFingerOddA (e, e') (a, a'), TwoFingerOddE e' a') Source #
>>>
alignLeftOddAEvenA (consOddA 'a' 1 $ consOddA 'b' 2 $ singletonOddA 'c') (consEvenA "foo" 10 mempty)
Left (consEvenA ('a',"foo") (1,10) mempty,consOddA 'b' 2 (singletonOddA 'c'))
>>>
alignLeftOddAEvenA (consOddA 'a' 1 $ singletonOddA 'b') (consEvenA "foo" 10 $ consEvenA "bar" 20 $ consEvenA "baz" 30 mempty)
Right (consOddA ('a',"foo") (1,10) (singletonOddA ('b',"bar")),consOddE 20 "baz" (singletonOddE 30))
\(AnyOddA as) (AnyEvenA bs) -> let { (as', bs') = case alignLeftOddAEvenA as bs of { Left (aligned, rest) -> (appendEvenAOddA (bimap fst fst aligned) rest, bimap snd snd aligned) ; Right (aligned, rest) -> (bimap fst fst aligned, appendOddAOddE (bimap snd snd aligned) rest) } } in as == as' && bs == bs'
alignLeftOddEOddE :: TwoFingerOddE e a -> TwoFingerOddE e' a' -> (TwoFingerOddE (e, e') (a, a'), Either (TwoFingerEvenA e a) (TwoFingerEvenA e' a')) Source #
>>>
alignLeftOddEOddE (consOddE 'a' 1 $ consOddE 'b' 2 $ singletonOddE 'c') (consOddE "foo" 10 $ singletonOddE "bar")
(consOddE ('a',"foo") (1,10) (singletonOddE ('b',"bar")),Left (consEvenA 2 'c' mempty))
>>>
alignLeftOddEOddE (consOddE 'a' 1 $ singletonOddE 'b') (consOddE "foo" 10 $ consOddE "bar" 20 $ singletonOddE "baz")
(consOddE ('a',"foo") (1,10) (singletonOddE ('b',"bar")),Right (consEvenA 20 "baz" mempty))
\(AnyOddE as) (AnyOddE bs) -> let { (aligned, rest) = alignLeftOddEOddE as bs ; as' = appendOddEEvenA (bimap fst fst aligned) (either id (const mempty) rest) ; bs' = appendOddEEvenA (bimap snd snd aligned) (either (const mempty) id rest) } in as == as' && bs == bs'
alignLeftOddEEvenE :: TwoFingerOddE e a -> TwoFingerEvenE e' a' -> Either (TwoFingerEvenE (e, e') (a, a'), TwoFingerOddE e a) (TwoFingerOddE (e, e') (a, a'), TwoFingerOddA e' a') Source #
\(AnyOddE as) (AnyEvenE bs) -> let { (as', bs') = case alignLeftOddEEvenE as bs of { Left (aligned, rest) -> (appendEvenEOddE (bimap fst fst aligned) rest, bimap snd snd aligned) ; Right (aligned, rest) -> (bimap fst fst aligned, appendOddEOddA (bimap snd snd aligned) rest) } } in as == as' && bs == bs'
Infinite trees
repeatOddA :: a -> e -> TwoFingerOddA e a Source #
Infinitely repeat the given a
and e
.
\(AnyOddA as) -> as == bimap (uncurry ($)) (uncurry ($)) (fst $ alignLeftOddAOddA (repeatOddA id id) as)
\(AnyEvenA as) -> either ((as ==) . bimap (uncurry ($)) (uncurry ($)) . fst) (const False) (alignLeftOddAEvenA (repeatOddA id id) as)
repeatOddE :: e -> a -> TwoFingerOddE e a Source #
Infinitely repeat the given a
and e
.
\(AnyOddE as) -> as == bimap (uncurry ($)) (uncurry ($)) (fst $ alignLeftOddEOddE (repeatOddE id id) as)
\(AnyEvenE as) -> either ((==) as . bimap (uncurry ($)) (uncurry ($)) . fst) (const False) $ alignLeftOddEEvenE (repeatOddE id id) as
repeatEvenA :: a -> e -> TwoFingerEvenA e a Source #
Infinitely repeat the given a
and e
.
\(AnyEvenA as) -> as == bimap (uncurry ($)) (uncurry ($)) (fst $ alignLeftEvenAEvenA (repeatEvenA id id) as)
\(AnyOddA as) -> either (const False) ((==) as . bimap (uncurry $ flip ($)) (uncurry $ flip ($)) . fst) $ alignLeftOddAEvenA as (repeatEvenA id id)
repeatEvenE :: e -> a -> TwoFingerEvenE e a Source #
\(AnyEvenE as) -> as == bimap (uncurry ($)) (uncurry ($)) (fst $ alignLeftEvenEEvenE (repeatEvenE id id) as)
\(AnyOddE as) -> either (const False) ((==) as . bimap (uncurry $ flip ($)) (uncurry $ flip ($)) . fst) $ alignLeftOddEEvenE as (repeatEvenE id id)
infiniteOddA :: Stream a -> Stream e -> Stream e -> Stream a -> TwoFingerOddA e a Source #
From streams of leftward a
, leftward e
, rightward e
and
rightward a
, build an infinite TwoFingerOddA
.
>>>
let infinite = infiniteOddA (Stream.iterate (+ 1) 0) (Stream.iterate (+ 1) 10) (Stream.iterate (+ 1) 20) (Stream.iterate (+ 1) 30)
>>>
take 5 $ unfoldr (hush . unconsOddA) infinite
[(0,10),(1,11),(2,12),(3,13),(4,14)]>>>
take 5 $ unfoldr (fmap swap . hush . unsnocOddA) infinite
[(20,30),(21,31),(22,32),(23,33),(24,34)]
infiniteOddE :: Stream e -> Stream a -> Stream a -> Stream e -> TwoFingerOddE e a Source #
>>>
let infinite = infiniteOddE (Stream.iterate (+ 1) 0) (Stream.iterate (+ 1) 10) (Stream.iterate (+ 1) 20) (Stream.iterate (+ 1) 30)
>>>
take 5 $ unfoldr (hush . unconsOddE) infinite
[(0,10),(1,11),(2,12),(3,13),(4,14)]>>>
take 5 $ unfoldr (fmap swap . hush . unsnocOddE) infinite
[(20,30),(21,31),(22,32),(23,33),(24,34)]
infiniteEvenA :: Stream a -> Stream e -> Stream a -> Stream e -> TwoFingerEvenA e a Source #
>>>
let infinite = infiniteEvenA (Stream.iterate (+ 1) 0) (Stream.iterate (+ 1) 10) (Stream.iterate (+ 1) 20) (Stream.iterate (+ 1) 30)
>>>
take 5 $ unfoldr unconsEvenA infinite
[(0,10),(1,11),(2,12),(3,13),(4,14)]>>>
take 5 $ unfoldr (fmap swap . unsnocEvenA) infinite
[(20,30),(21,31),(22,32),(23,33),(24,34)]
infiniteEvenE :: Stream e -> Stream a -> Stream e -> Stream a -> TwoFingerEvenE e a Source #
>>>
let infinite = infiniteEvenE (Stream.iterate (+ 1) 0) (Stream.iterate (+ 1) 10) (Stream.iterate (+ 1) 20) (Stream.iterate (+ 1) 30)
>>>
take 5 $ unfoldr unconsEvenE infinite
[(0,10),(1,11),(2,12),(3,13),(4,14)]>>>
take 5 $ unfoldr (fmap swap . unsnocEvenE) infinite
[(20,30),(21,31),(22,32),(23,33),(24,34)]