Skip to content

Commit

Permalink
Merge pull request #15 from KamchatkaLtd/finger
Browse files Browse the repository at this point in the history
#4 - Add finger tree concatenation
  • Loading branch information
alf239 authored May 5, 2019
2 parents 2f6d823 + ab89038 commit e7e2bad
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 4 deletions.
6 changes: 4 additions & 2 deletions src/main/scala/finger/FingerTreeDeque.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package finger

import finger.Fingers.{Empty, FingerTree}
import okasaki.Deque
import okasaki.CatenableDeque

class FingerTreeDeque[E] extends Deque[E, FingerTree[E]] {
class FingerTreeDeque[E] extends CatenableDeque[E, FingerTree[E]] {
override def init(q: FingerTree[E]): FingerTree[E] = Fingers.init(q)

override def last(q: FingerTree[E]): E = Fingers.last(q)
Expand All @@ -19,4 +19,6 @@ class FingerTreeDeque[E] extends Deque[E, FingerTree[E]] {
override def head(q: FingerTree[E]): E = Fingers.head(q)

override def tail(q: FingerTree[E]): FingerTree[E] = Fingers.tail(q)

override def ++(a: FingerTree[E], b: FingerTree[E]): FingerTree[E] = Fingers.concat(a, b)
}
22 changes: 22 additions & 0 deletions src/main/scala/finger/Fingers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -222,4 +222,26 @@ object Fingers {
case NilR => throw new IllegalStateException("init() of an empty tree")
case SnocR(t, _) => t
}

// ==========================================================================================
def app3[A](fta: FingerTree[A], ts: List[A], ftb: FingerTree[A]): FingerTree[A] =
(fta, ftb) match {
case (Empty, xs) => cons1(ts, xs)
case (xs, Empty) => snoc1(xs, ts)
case (Single(x), xs) => cons(x, cons1(ts, xs))
case (xs, Single(x)) => snoc(snoc1(xs, ts), x)
case (Deep(pr1, m1, sf1), Deep(pr2, m2, sf2)) =>
Deep(pr1, app3(m1, nodes(toList(sf1) ++ ts ++ toList(pr2)), m2), sf2)
}

def nodes[A](xs: List[A]): List[Node[A]] = xs match {
case List(a, b) => List(Node2(a, b))
case List(a, b, c) => List(Node3(a, b, c))
case List(a, b, c, d) => List(Node2(a, b), Node2(c, d))
case a :: b :: c :: rest => Node3(a, b, c) :: nodes(rest)
}

def concat[A](xs: FingerTree[A], ys: FingerTree[A]): FingerTree[A] =
app3(xs, Nil, ys)

}
4 changes: 2 additions & 2 deletions src/test/scala/finger/FingerTreeDequeSpec.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package finger

import okasaki.{DequeSpec, IntElements}
import okasaki.{CatenableDequeSpec, IntElements}

class FingerTreeDequeSpec extends DequeSpec(new FingerTreeDeque[Int])
class FingerTreeDequeSpec extends CatenableDequeSpec(new FingerTreeDeque[Int])
with IntElements

0 comments on commit e7e2bad

Please sign in to comment.