-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#4 - Initial draft of finger tree structures (WIP)
- Loading branch information
Showing
1 changed file
with
68 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package finger | ||
|
||
import scala.language.higherKinds | ||
|
||
object Fingers { | ||
|
||
// ========================================================================================== | ||
sealed trait FingerTree[+A] | ||
|
||
case object Empty extends FingerTree[Nothing] | ||
|
||
case class Single[A](a: A) extends FingerTree[A] | ||
|
||
case class Deep[A](l: Digit[A], down: FingerTree[Node[A]], r: Digit[A]) extends FingerTree[A] | ||
|
||
// ========================================================================================== | ||
sealed trait Node[A] | ||
|
||
case class Node2[A](a: A, b: A) extends Node[A] | ||
|
||
case class Node3[A](a: A, b: A, c: A) extends Node[A] | ||
|
||
// ========================================================================================== | ||
type Digit[A] = List[A] | ||
|
||
// ========================================================================================== | ||
trait Reduce[F[_]] { | ||
def reducer[A, B](fn: (A, B) => B): (F[A], B) => B | ||
|
||
def reducel[A, B](fn: (B, A) => B): (B, F[A]) => B | ||
} | ||
|
||
implicit val listReduce: Reduce[List] = new Reduce[List] { | ||
override def reducer[A, B](fn: (A, B) => B): (List[A], B) => B = (as, b) => as.foldRight(b)(fn) | ||
|
||
override def reducel[A, B](fn: (B, A) => B): (B, List[A]) => B = (b, as) => as.foldLeft(b)(fn) | ||
} | ||
|
||
def toList[A, F[_] : Reduce](s: F[A]): List[A] = | ||
implicitly[Reduce[F]].reducer[A, List[A]](_ :: _)(s, Nil) | ||
|
||
// ========================================================================================== | ||
implicit val nodeReduce: Reduce[Node] = new Reduce[Node] { | ||
override def reducer[A, B](fn: (A, B) => B): (Node[A], B) => B = (na, z) => na match { | ||
case Node2(a, b) => fn(a, fn(b, z)) | ||
case Node3(a, b, c) => fn(a, fn(b, fn(c, z))) | ||
} | ||
|
||
override def reducel[A, B](fn: (B, A) => B): (B, Node[A]) => B = (z, na) => na match { | ||
case Node2(a, b) => fn(z, fn(b, a)) | ||
case Node3(a, b, c) => fn(fn(fn(z, c), b), a) | ||
} | ||
} | ||
|
||
implicit val fingerTreeReduce: Reduce[FingerTree] = new Reduce[FingerTree] { | ||
override def reducer[A, B](fn: (A, B) => B): (FingerTree[A], B) => B = (fta, z) => fta match { | ||
case Empty => z | ||
case Single(a) => fn(a, z) | ||
case Deep(pr, m, sf) => ??? | ||
} | ||
|
||
override def reducel[A, B](fn: (B, A) => B): (B, FingerTree[A]) => B = (z, fta) => fta match { | ||
case Empty => z | ||
case Single(a) => fn(z, a) | ||
case Deep(pr, m, sf) => ??? | ||
} | ||
} | ||
} |