Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package tutorial
- class RNode[+A] {
- //My attempt to abstract away case matching
- def ifNullThenElse[B >: A,C](ifNull:C,ifNot:Node[A]=>C): C =
- this match {
- case NullNode => ifNull
- case node:Node[B] => ifNot(node)
- }
- //Its use
- def hasNext [B >: A]: Boolean =
- ifNullThenElse(false, { case Node(_,n) =>
- n != null })
- def findLast[B >: A]: RNode[B] =
- ifNullThenElse(NullNode,{ node:Node[B] =>
- if (node.hasNext) (getNext.findLast)
- else node })
- def getNext[B >: A]: RNode[B] =
- ifNullThenElse(NullNode,{ case Node(_,n) => n })
- def foreach[B >: A, C](f: B => C): RNode[C] =
- ifNullThenElse(NullNode,{ case Node(c,n) =>
- Node( f(c) , n.foreach(f) ) })
- def replaceTail[B >: A](newTail:RNode[B]): RNode[B] =
- ifNullThenElse(newTail,{ case Node(c,n) =>
- Node( c , newTail ) })
- def unsafeGetCargo[B >: A]: B =
- ifNullThenElse(throw new Exception("getCargo called on a NullNode"),
- { case Node(c,n) => c })
- def safeGetCargo[B >: A]: Option[B] =
- ifNullThenElse(None,{ case Node(c,n) => Some(c) })
- }
- case class Node[+A](cargo:A,next:RNode[A] = NullNode) extends RNode[A]
- case object NullNode extends RNode[Nothing]
- class LinkedList[A] {
- var head: RNode[A] = NullNode
- var last: RNode[A] = head
- var size: Int = 0
- def this(head:RNode[A], last:RNode[A]) = {
- this
- this.head = head
- this.last = last
- }
- def length: Int = size
- def maxIndex: Int = size - 1
- def pushFront(cargo:A) = {
- val oldHead = head
- head = Node(cargo).replaceTail(oldHead)
- size += 1
- }
- def pushBack(cargo:A) = {
- last.replaceTail(Node(cargo))
- last = last.getNext
- size += 1
- }
- def foreach[B](f: A => B): LinkedList[B] = {
- val newHead = head.foreach(f)
- new LinkedList(newHead, newHead.findLast)
- }
- def get(index:Int): A = {
- var curNode = head
- for (i <- 0 to maxIndex) {
- curNode = curNode.getNext
- }
- curNode.unsafeGetCargo
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment