From b65a8d91f6d10668705d63d5ef2e076193fde513 Mon Sep 17 00:00:00 2001 From: Zhenia Trochun Date: Fri, 8 Jun 2018 00:31:16 +0300 Subject: [PATCH 1/2] Added simple Scala examples --- Scala/.gitignore | 3 ++ Scala/src/Example.scala | 26 ++++++++++ Scala/src/doubleLinked/DoubleLinked.scala | 60 +++++++++++++++++++++ Scala/src/singleLinked/SingleLinked.scala | 63 +++++++++++++++++++++++ 4 files changed, 152 insertions(+) create mode 100644 Scala/.gitignore create mode 100644 Scala/src/Example.scala create mode 100644 Scala/src/doubleLinked/DoubleLinked.scala create mode 100644 Scala/src/singleLinked/SingleLinked.scala diff --git a/Scala/.gitignore b/Scala/.gitignore new file mode 100644 index 0000000..e6ebc35 --- /dev/null +++ b/Scala/.gitignore @@ -0,0 +1,3 @@ +.idea/ +target/ +*.iml \ No newline at end of file diff --git a/Scala/src/Example.scala b/Scala/src/Example.scala new file mode 100644 index 0000000..93439d9 --- /dev/null +++ b/Scala/src/Example.scala @@ -0,0 +1,26 @@ +import doubleLinked.{DNil, DoubleLinked} +import singleLinked.{SNil, SingleLinked} + +object Example { + def main(args: Array[String]): Unit = { + val list: SingleLinked[Int] = 1 :: 2 :: 3 :: SNil + + list.foreach(item => print(s"$item\t")) + println() + + list.map(_ + 1).foreach(item => print(s"$item\t")) + println() + + list.flatMap(item => item :: item :: singleLinked.SNil).foreach(item => print(s"$item\t")) + println() + + + val list2: DoubleLinked[Int] = 1 :: 2 :: 3 :: DNil + + list2.foreach(item => print(s"$item\t")) + println() + + list2.map(_ + 1).foreach(item => print(s"$item\t")) + println() + } +} \ No newline at end of file diff --git a/Scala/src/doubleLinked/DoubleLinked.scala b/Scala/src/doubleLinked/DoubleLinked.scala new file mode 100644 index 0000000..1297861 --- /dev/null +++ b/Scala/src/doubleLinked/DoubleLinked.scala @@ -0,0 +1,60 @@ +package doubleLinked + +/** + * In case of double linked list we have to ignore some principles of functional programming + * and we have to make some fields of Node class mutable + * In other case we will have to recreate all list after any change + */ + +sealed trait DoubleLinked[+A] { + def ::[B >: A](x: B): DoubleLinked[B] = { + DoubleLinked.append(x, this) + } + + def foreach[B >: A](f: B => Unit): Unit = { + DoubleLinked.foreach(this)(f) + } + + def map[B](f: A => B): DoubleLinked[B] = { + DoubleLinked.map(this, DNil)(f) + } +} + + +case object DNil extends DoubleLinked[Nothing] +class Node[A](var prev: DoubleLinked[A], val value: A, var next: DoubleLinked[A]) extends DoubleLinked[A] + + +object DoubleLinked { + def empty[A]: DoubleLinked[A] = DNil + + def apply[A](values: A*): DoubleLinked[A] = values.foldLeft(DoubleLinked.empty[A])((list, item) => item :: list) + + def append[A](x: A, list: DoubleLinked[A]): DoubleLinked[A] = { + val node = new Node(DNil, x, list) + list match { + case DNil => DNil + case l: Node[A] => + l.prev = node + } + + node + } + + def foreach[A](list: DoubleLinked[A])(f: A => Unit): Unit = { + list match { + case DNil => + case l: Node[A] => + f(l.value) + l.next.foreach(f) + } + } + + def map[A, B](list: DoubleLinked[A], prev: DoubleLinked[B])(f: A => B): DoubleLinked[B] = { + list match { + case DNil => DNil + case l: Node[A] => + new Node(prev, f(l.value), map(l.next, prev)(f)) + } + } +} \ No newline at end of file diff --git a/Scala/src/singleLinked/SingleLinked.scala b/Scala/src/singleLinked/SingleLinked.scala new file mode 100644 index 0000000..208eabd --- /dev/null +++ b/Scala/src/singleLinked/SingleLinked.scala @@ -0,0 +1,63 @@ +package singleLinked + + +sealed trait SingleLinked[+A] { + def ::[B >: A](x: B): SingleLinked[B] = { + SingleLinked.::(x, this) + } + + def foreach[B >: A](f: B => Unit): Unit = { + SingleLinked.foreach(this)(f) + } + + def map[B](f: A => B): SingleLinked[B] = { + SingleLinked.map(this)(f) + } + + def flatMap[B](f: A => SingleLinked[B]): SingleLinked[B] = { + SingleLinked.flatMap(this)(f) + } +} + + +case object SNil extends SingleLinked[Nothing] +case class Node[+A](value: A, next: SingleLinked[A]) extends SingleLinked[A] + + +object SingleLinked { + def empty[A]: SingleLinked[A] = SNil + + def apply[A](values: A*): SingleLinked[A] = values.foldLeft(SingleLinked.empty[A])((list, item) => item :: list) + + def ::[A](x: A, list: SingleLinked[A]): SingleLinked[A] = Node(x, list) + + def foreach[A](list: SingleLinked[A])(f: A => Unit): Unit = { + list match { + case SNil => + case Node(x, next) => + f(x) + next.foreach(f) + } + } + + def map[A, B](list: SingleLinked[A])(f: A => B): SingleLinked[B] = { + list match { + case SNil => SNil + case Node(x, next) => Node(f(x), next.map(f)) + } + } + + def merge[A](list1: SingleLinked[A], list2: SingleLinked[A]): SingleLinked[A] = { + list1 match { + case SNil => list2 + case Node(x, next) => Node(x, merge(next, list2)) + } + } + + def flatMap[A, B](list: SingleLinked[A])(f: A => SingleLinked[B]): SingleLinked[B] = { + list match { + case SNil => SNil + case Node(x, next) => merge(f(x), next.flatMap(f)) + } + } +} \ No newline at end of file From fca63958354f6d82f17b71ebabbe2cacb199ad33 Mon Sep 17 00:00:00 2001 From: Zhenia Trochun Date: Sat, 9 Jun 2018 10:09:06 +0300 Subject: [PATCH 2/2] names refactored and empty lines added --- Scala/.gitignore | 2 +- ...eLinked.scala => 1-single-immutable.scala} | 41 ++++++++++++------- ...bleLinked.scala => 2-doubly-mutable.scala} | 37 +++++++++++------ Scala/src/Example.scala | 26 ------------ 4 files changed, 52 insertions(+), 54 deletions(-) rename Scala/{src/singleLinked/SingleLinked.scala => 1-single-immutable.scala} (54%) rename Scala/{src/doubleLinked/DoubleLinked.scala => 2-doubly-mutable.scala} (56%) delete mode 100644 Scala/src/Example.scala diff --git a/Scala/.gitignore b/Scala/.gitignore index e6ebc35..b4a5277 100644 --- a/Scala/.gitignore +++ b/Scala/.gitignore @@ -1,3 +1,3 @@ .idea/ target/ -*.iml \ No newline at end of file +*.iml diff --git a/Scala/src/singleLinked/SingleLinked.scala b/Scala/1-single-immutable.scala similarity index 54% rename from Scala/src/singleLinked/SingleLinked.scala rename to Scala/1-single-immutable.scala index 208eabd..2f071ab 100644 --- a/Scala/src/singleLinked/SingleLinked.scala +++ b/Scala/1-single-immutable.scala @@ -1,9 +1,6 @@ -package singleLinked - - sealed trait SingleLinked[+A] { - def ::[B >: A](x: B): SingleLinked[B] = { - SingleLinked.::(x, this) + def ::[B >: A](value: B): SingleLinked[B] = { + SingleLinked.::(value, this) } def foreach[B >: A](f: B => Unit): Unit = { @@ -21,7 +18,7 @@ sealed trait SingleLinked[+A] { case object SNil extends SingleLinked[Nothing] -case class Node[+A](value: A, next: SingleLinked[A]) extends SingleLinked[A] +case class SNode[+A](value: A, tail: SingleLinked[A]) extends SingleLinked[A] object SingleLinked { @@ -29,35 +26,51 @@ object SingleLinked { def apply[A](values: A*): SingleLinked[A] = values.foldLeft(SingleLinked.empty[A])((list, item) => item :: list) - def ::[A](x: A, list: SingleLinked[A]): SingleLinked[A] = Node(x, list) + def ::[A](value: A, list: SingleLinked[A]): SingleLinked[A] = SNode(value, list) def foreach[A](list: SingleLinked[A])(f: A => Unit): Unit = { list match { case SNil => - case Node(x, next) => - f(x) - next.foreach(f) + case SNode(value, tail) => + f(value) + tail.foreach(f) } } def map[A, B](list: SingleLinked[A])(f: A => B): SingleLinked[B] = { list match { case SNil => SNil - case Node(x, next) => Node(f(x), next.map(f)) + case SNode(value, tail) => SNode(f(value), tail.map(f)) } } def merge[A](list1: SingleLinked[A], list2: SingleLinked[A]): SingleLinked[A] = { list1 match { case SNil => list2 - case Node(x, next) => Node(x, merge(next, list2)) + case SNode(value, tail) => SNode(value, merge(tail, list2)) } } def flatMap[A, B](list: SingleLinked[A])(f: A => SingleLinked[B]): SingleLinked[B] = { list match { case SNil => SNil - case Node(x, next) => merge(f(x), next.flatMap(f)) + case SNode(value, tail) => merge(f(value), tail.flatMap(f)) } } -} \ No newline at end of file +} + +object SingleExample { + + def main(args: Array[String]): Unit = { + val list: SingleLinked[Int] = 1 :: 2 :: 3 :: SNil + + list.foreach(item => print(s"$item\t")) + println() + + list.map(_ + 1).foreach(item => print(s"$item\t")) + println() + + list.flatMap(item => item :: item :: SNil).foreach(item => print(s"$item\t")) + println() + } +} diff --git a/Scala/src/doubleLinked/DoubleLinked.scala b/Scala/2-doubly-mutable.scala similarity index 56% rename from Scala/src/doubleLinked/DoubleLinked.scala rename to Scala/2-doubly-mutable.scala index 1297861..0e62007 100644 --- a/Scala/src/doubleLinked/DoubleLinked.scala +++ b/Scala/2-doubly-mutable.scala @@ -1,14 +1,12 @@ -package doubleLinked - /** * In case of double linked list we have to ignore some principles of functional programming - * and we have to make some fields of Node class mutable + * and we should make some fields of Node class mutable * In other case we will have to recreate all list after any change */ sealed trait DoubleLinked[+A] { - def ::[B >: A](x: B): DoubleLinked[B] = { - DoubleLinked.append(x, this) + def ::[B >: A](value: B): DoubleLinked[B] = { + DoubleLinked.append(value, this) } def foreach[B >: A](f: B => Unit): Unit = { @@ -22,7 +20,7 @@ sealed trait DoubleLinked[+A] { case object DNil extends DoubleLinked[Nothing] -class Node[A](var prev: DoubleLinked[A], val value: A, var next: DoubleLinked[A]) extends DoubleLinked[A] +class DNode[A](var prev: DoubleLinked[A], val value: A, var next: DoubleLinked[A]) extends DoubleLinked[A] object DoubleLinked { @@ -30,11 +28,11 @@ object DoubleLinked { def apply[A](values: A*): DoubleLinked[A] = values.foldLeft(DoubleLinked.empty[A])((list, item) => item :: list) - def append[A](x: A, list: DoubleLinked[A]): DoubleLinked[A] = { - val node = new Node(DNil, x, list) + def append[A](value: A, list: DoubleLinked[A]): DoubleLinked[A] = { + val node = new DNode(DNil, value, list) list match { case DNil => DNil - case l: Node[A] => + case l: DNode[A] => l.prev = node } @@ -44,7 +42,7 @@ object DoubleLinked { def foreach[A](list: DoubleLinked[A])(f: A => Unit): Unit = { list match { case DNil => - case l: Node[A] => + case l: DNode[A] => f(l.value) l.next.foreach(f) } @@ -53,8 +51,21 @@ object DoubleLinked { def map[A, B](list: DoubleLinked[A], prev: DoubleLinked[B])(f: A => B): DoubleLinked[B] = { list match { case DNil => DNil - case l: Node[A] => - new Node(prev, f(l.value), map(l.next, prev)(f)) + case l: DNode[A] => + new DNode(prev, f(l.value), map(l.next, prev)(f)) } } -} \ No newline at end of file +} + +object DoublyExample { + + def main(args: Array[String]): Unit = { + val list2: DoubleLinked[Int] = 1 :: 2 :: 3 :: DNil + + list2.foreach(item => print(s"$item\t")) + println() + + list2.map(_ + 1).foreach(item => print(s"$item\t")) + println() + } +} diff --git a/Scala/src/Example.scala b/Scala/src/Example.scala deleted file mode 100644 index 93439d9..0000000 --- a/Scala/src/Example.scala +++ /dev/null @@ -1,26 +0,0 @@ -import doubleLinked.{DNil, DoubleLinked} -import singleLinked.{SNil, SingleLinked} - -object Example { - def main(args: Array[String]): Unit = { - val list: SingleLinked[Int] = 1 :: 2 :: 3 :: SNil - - list.foreach(item => print(s"$item\t")) - println() - - list.map(_ + 1).foreach(item => print(s"$item\t")) - println() - - list.flatMap(item => item :: item :: singleLinked.SNil).foreach(item => print(s"$item\t")) - println() - - - val list2: DoubleLinked[Int] = 1 :: 2 :: 3 :: DNil - - list2.foreach(item => print(s"$item\t")) - println() - - list2.map(_ + 1).foreach(item => print(s"$item\t")) - println() - } -} \ No newline at end of file