From 85af1fc601005b541f90d4ef6c6b55298273b386 Mon Sep 17 00:00:00 2001 From: odbc Date: Thu, 14 Jun 2018 23:48:50 +0300 Subject: [PATCH 1/2] Week 1: task 1 --- src/main/scala/fpspeedrun/Eq.scala | 20 +++++++++- src/main/scala/fpspeedrun/Ord.scala | 54 ++++++++++++++++++++++++--- src/main/scala/fpspeedrun/Ratio.scala | 2 +- 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/src/main/scala/fpspeedrun/Eq.scala b/src/main/scala/fpspeedrun/Eq.scala index 7343eaa..4c45334 100644 --- a/src/main/scala/fpspeedrun/Eq.scala +++ b/src/main/scala/fpspeedrun/Eq.scala @@ -1,5 +1,23 @@ package fpspeedrun trait Eq[T] { - def ===(x: T, y: T): Boolean + def ===(x: T, y: T): Boolean = ! !==(x, y) + def !==(x: T, y: T): Boolean = ! ===(x, y) } + +object Eq { + + implicit class EqOps[T](val x: T) extends AnyVal{ + def ===(y: T)(implicit eq: Eq[T]): Boolean = eq.===(x, y) + def !==(y: T)(implicit eq: Eq[T]): Boolean = eq.!==(x, y) + } + + implicit val ratioEq: Eq[Ratio] = new Eq[Ratio] { + override def ===(x: Ratio, y: Ratio): Boolean = x.numerator * y.denominator == y.numerator * x.denominator + } + + implicit def listEq[T : Eq]: Eq[List[T]] = new Eq[List[T]] { + override def ===(x: List[T], y: List[T]): Boolean = x.size == y.size && (x zip y forall { case (a: T, b: T) => implicitly[Eq[T]].===(a, b) }) + } + +} \ No newline at end of file diff --git a/src/main/scala/fpspeedrun/Ord.scala b/src/main/scala/fpspeedrun/Ord.scala index 231eec3..a0ebaf6 100644 --- a/src/main/scala/fpspeedrun/Ord.scala +++ b/src/main/scala/fpspeedrun/Ord.scala @@ -1,15 +1,57 @@ package fpspeedrun -import fpspeedrun.Ord.Compare -trait Ord[T] extends Eq[T]{ +import fpspeedrun.Ord.{Compare, EQ, GT, LT} + +trait Ord[T] extends Eq[T] { + override def ===(x: T, y: T): Boolean = compare(x, y) == EQ def compare(x: T, y: T): Compare } object Ord{ sealed trait Compare - object Compare{ - case object LT //less than - case object EQ //equals to - case object GT //greater than + + case object LT extends Compare //less than + case object EQ extends Compare //equals to + case object GT extends Compare //greater than + + implicit class OrdOps[T](val x: T) extends AnyVal { + def ===(y: T)(implicit ord: Ord[T]): Boolean = ord.===(x, y) + def !==(y: T)(implicit ord: Ord[T]): Boolean = ord.!==(x, y) + def compare(y: T)(implicit ord: Ord[T]): Compare = ord.compare(x, y) + } + + implicit val ratioOrd: Ord[Ratio] = (x: Ratio, y: Ratio) => { + val leftUpToRightDown: Int = x.numerator * y.denominator + val leftDownToRightUp: Int = x.denominator * y.numerator + + if (leftUpToRightDown > leftDownToRightUp) GT + else if (leftUpToRightDown < leftDownToRightUp) LT + else EQ + } + + implicit def lexicographicalListOrd[T : Ord]: Ord[List[T]] = (x: List[T], y: List[T]) => (x, y) match { + case (a, b) if a.isEmpty && b.isEmpty => EQ + case (a, b) if a.isEmpty && b.nonEmpty => LT + case (a, b) if a.nonEmpty && b.isEmpty => GT + case (a :: as, b :: bs) => + val cmp = a compare b + if (cmp == EQ) as compare bs else cmp } } + +object OrdInstances { + import Ord.OrdOps + + implicit def sizeFirstListOrd[T : Ord]: Ord[List[T]] = (x: List[T], y: List[T]) => + if (x.size < y.size) LT + else if (x.size > y.size) GT + else x zip y find { case (a, b) => a !== b } match { + case Some((a, b)) => a compare b + case None => EQ + } + + implicit def sizeOnlyListOrd[T : Ord]: Ord[List[T]] = (x: List[T], y: List[T]) => + if (x.size < y.size) LT + else if (x.size > y.size) GT + else EQ +} \ No newline at end of file diff --git a/src/main/scala/fpspeedrun/Ratio.scala b/src/main/scala/fpspeedrun/Ratio.scala index bc3fe1b..e107992 100644 --- a/src/main/scala/fpspeedrun/Ratio.scala +++ b/src/main/scala/fpspeedrun/Ratio.scala @@ -1,4 +1,4 @@ package fpspeedrun -final case class Ratio() +final case class Ratio(numerator: Int, denominator: Int) From dda6b23aeac4e325b2954f882c10331e8ef1f7ca Mon Sep 17 00:00:00 2001 From: odbc Date: Sat, 16 Jun 2018 00:26:47 +0300 Subject: [PATCH 2/2] Week 1: task 1 (edited) --- src/main/scala/fpspeedrun/Eq.scala | 12 ++--- src/main/scala/fpspeedrun/Ord.scala | 47 ++++---------------- src/main/scala/fpspeedrun/OrdInstances.scala | 21 +++++++++ src/main/scala/fpspeedrun/Ratio.scala | 13 ++++++ src/main/scala/fpspeedrun/syntax.scala | 19 +++++++- 5 files changed, 63 insertions(+), 49 deletions(-) create mode 100644 src/main/scala/fpspeedrun/OrdInstances.scala diff --git a/src/main/scala/fpspeedrun/Eq.scala b/src/main/scala/fpspeedrun/Eq.scala index 4c45334..02fa50f 100644 --- a/src/main/scala/fpspeedrun/Eq.scala +++ b/src/main/scala/fpspeedrun/Eq.scala @@ -7,17 +7,11 @@ trait Eq[T] { object Eq { - implicit class EqOps[T](val x: T) extends AnyVal{ - def ===(y: T)(implicit eq: Eq[T]): Boolean = eq.===(x, y) - def !==(y: T)(implicit eq: Eq[T]): Boolean = eq.!==(x, y) - } - - implicit val ratioEq: Eq[Ratio] = new Eq[Ratio] { - override def ===(x: Ratio, y: Ratio): Boolean = x.numerator * y.denominator == y.numerator * x.denominator - } + import syntax.eq.EqOps implicit def listEq[T : Eq]: Eq[List[T]] = new Eq[List[T]] { - override def ===(x: List[T], y: List[T]): Boolean = x.size == y.size && (x zip y forall { case (a: T, b: T) => implicitly[Eq[T]].===(a, b) }) + override def ===(x: List[T], y: List[T]): Boolean = + x.size == y.size && ( x zip y forall { case (a: T, b: T) => a === b } ) } } \ No newline at end of file diff --git a/src/main/scala/fpspeedrun/Ord.scala b/src/main/scala/fpspeedrun/Ord.scala index a0ebaf6..dc1e91e 100644 --- a/src/main/scala/fpspeedrun/Ord.scala +++ b/src/main/scala/fpspeedrun/Ord.scala @@ -1,57 +1,26 @@ package fpspeedrun -import fpspeedrun.Ord.{Compare, EQ, GT, LT} +import fpspeedrun.Ord.{Compare, EQ} trait Ord[T] extends Eq[T] { override def ===(x: T, y: T): Boolean = compare(x, y) == EQ def compare(x: T, y: T): Compare } -object Ord{ +object Ord { + sealed trait Compare case object LT extends Compare //less than case object EQ extends Compare //equals to case object GT extends Compare //greater than - implicit class OrdOps[T](val x: T) extends AnyVal { - def ===(y: T)(implicit ord: Ord[T]): Boolean = ord.===(x, y) - def !==(y: T)(implicit ord: Ord[T]): Boolean = ord.!==(x, y) - def compare(y: T)(implicit ord: Ord[T]): Compare = ord.compare(x, y) - } - - implicit val ratioOrd: Ord[Ratio] = (x: Ratio, y: Ratio) => { - val leftUpToRightDown: Int = x.numerator * y.denominator - val leftDownToRightUp: Int = x.denominator * y.numerator - - if (leftUpToRightDown > leftDownToRightUp) GT - else if (leftUpToRightDown < leftDownToRightUp) LT - else EQ - } - - implicit def lexicographicalListOrd[T : Ord]: Ord[List[T]] = (x: List[T], y: List[T]) => (x, y) match { - case (a, b) if a.isEmpty && b.isEmpty => EQ - case (a, b) if a.isEmpty && b.nonEmpty => LT - case (a, b) if a.nonEmpty && b.isEmpty => GT - case (a :: as, b :: bs) => - val cmp = a compare b - if (cmp == EQ) as compare bs else cmp - } -} - -object OrdInstances { - import Ord.OrdOps + import syntax.ord.OrdOps - implicit def sizeFirstListOrd[T : Ord]: Ord[List[T]] = (x: List[T], y: List[T]) => - if (x.size < y.size) LT - else if (x.size > y.size) GT - else x zip y find { case (a, b) => a !== b } match { + implicit def lexicographicalListOrd[T : Ord]: Ord[List[T]] = (x: List[T], y: List[T]) => + x zip y find { case (a, b) => a !== b } match { case Some((a, b)) => a compare b - case None => EQ + case None => if (x.size < y.size) LT else if (x.size > y.size) GT else EQ } - implicit def sizeOnlyListOrd[T : Ord]: Ord[List[T]] = (x: List[T], y: List[T]) => - if (x.size < y.size) LT - else if (x.size > y.size) GT - else EQ -} \ No newline at end of file +} diff --git a/src/main/scala/fpspeedrun/OrdInstances.scala b/src/main/scala/fpspeedrun/OrdInstances.scala new file mode 100644 index 0000000..2af5fbd --- /dev/null +++ b/src/main/scala/fpspeedrun/OrdInstances.scala @@ -0,0 +1,21 @@ +package fpspeedrun + +import fpspeedrun.Ord.{EQ, GT, LT} +import syntax.ord.OrdOps + +object OrdInstances { + + implicit def sizeFirstListOrd[T : Ord]: Ord[List[T]] = (x: List[T], y: List[T]) => + if (x.size < y.size) LT + else if (x.size > y.size) GT + else x zip y find { case (a, b) => a !== b } match { + case Some((a, b)) => a compare b + case None => EQ + } + + implicit def sizeOnlyListOrd[T : Ord]: Ord[List[T]] = (x: List[T], y: List[T]) => + if (x.size < y.size) LT + else if (x.size > y.size) GT + else EQ + +} diff --git a/src/main/scala/fpspeedrun/Ratio.scala b/src/main/scala/fpspeedrun/Ratio.scala index e107992..af4eba0 100644 --- a/src/main/scala/fpspeedrun/Ratio.scala +++ b/src/main/scala/fpspeedrun/Ratio.scala @@ -1,4 +1,17 @@ package fpspeedrun +import fpspeedrun.Ord.{EQ, GT, LT} + final case class Ratio(numerator: Int, denominator: Int) +object Ratio { + + implicit val ratioOrd: Ord[Ratio] = (x: Ratio, y: Ratio) => { + val crossProductsDiff: Int = x.numerator * y.denominator - x.denominator * y.numerator + + if (crossProductsDiff > 0) GT + else if (crossProductsDiff < 0) LT + else EQ + } + +} diff --git a/src/main/scala/fpspeedrun/syntax.scala b/src/main/scala/fpspeedrun/syntax.scala index d4f9a19..cafc60b 100644 --- a/src/main/scala/fpspeedrun/syntax.scala +++ b/src/main/scala/fpspeedrun/syntax.scala @@ -1,9 +1,26 @@ package fpspeedrun +import fpspeedrun.Ord.Compare + object syntax { - object eq{ + + object eq { + implicit class EqOps[T](val x: T) extends AnyVal{ def ===(y: T)(implicit eq: Eq[T]): Boolean = eq.===(x, y) + def !==(y: T)(implicit eq: Eq[T]): Boolean = eq.!==(x, y) + } + + } + + object ord { + + implicit class OrdOps[T](val x: T) extends AnyVal { + def ===(y: T)(implicit ord: Ord[T]): Boolean = ord.===(x, y) + def !==(y: T)(implicit ord: Ord[T]): Boolean = ord.!==(x, y) + def compare(y: T)(implicit ord: Ord[T]): Compare = ord.compare(x, y) } + } + }