From 766b971ee33f2cf4b56e004084a927ab11a833f1 Mon Sep 17 00:00:00 2001 From: "Lan, Jian" Date: Mon, 28 Dec 2020 11:40:22 -0800 Subject: [PATCH 1/4] Fix links in source file and rename files and objects to fit the update to date terminology --- ...ontextQueries.scala => ContextFunctions.scala} | 11 +++++------ ...mpliedInstances.scala => GivenInstances.scala} | 5 ++--- src/main/scala/Main.scala | 7 +++---- ...aramTupling.scala => ParameterUntupling.scala} | 8 +++----- src/main/scala/PatternMatching.scala | 15 +++++++-------- src/main/scala/StructuralTypes.scala | 1 - 6 files changed, 20 insertions(+), 27 deletions(-) rename src/main/scala/{ContextQueries.scala => ContextFunctions.scala} (75%) rename src/main/scala/{ImpliedInstances.scala => GivenInstances.scala} (90%) rename src/main/scala/{AutoParamTupling.scala => ParameterUntupling.scala} (79%) diff --git a/src/main/scala/ContextQueries.scala b/src/main/scala/ContextFunctions.scala similarity index 75% rename from src/main/scala/ContextQueries.scala rename to src/main/scala/ContextFunctions.scala index 652cfc1..0028fac 100644 --- a/src/main/scala/ContextQueries.scala +++ b/src/main/scala/ContextFunctions.scala @@ -1,13 +1,12 @@ - import scala.concurrent.{ExecutionContext, Future} import scala.util.Try /** - * Context Queries: - * - http://dotty.epfl.ch/docs/reference/contextual/query-types.html, + * Context Functions: + * - https://dotty.epfl.ch/docs/reference/contextual/context-functions.html * - https://www.scala-lang.org/blog/2016/12/07/implicit-function-types.html */ -object ContextQueries /* Formerly known as Implicit Function Types */ { +object ContextFunctions { object context { // type alias Contextual @@ -21,10 +20,10 @@ object ContextQueries /* Formerly known as Implicit Function Types */ { object parse { - type Parseable[T] = ImpliedInstances.StringParser[T] ?=> Try[T] + type Parseable[T] = GivenInstances.StringParser[T] ?=> Try[T] def sumStrings(x: String, y: String): Parseable[Int] = { - val parser = implicitly[ImpliedInstances.StringParser[Int]] + val parser = implicitly[GivenInstances.StringParser[Int]] val tryA = parser.parse(x) val tryB = parser.parse(y) diff --git a/src/main/scala/ImpliedInstances.scala b/src/main/scala/GivenInstances.scala similarity index 90% rename from src/main/scala/ImpliedInstances.scala rename to src/main/scala/GivenInstances.scala index 9ca7ef2..0fecd99 100644 --- a/src/main/scala/ImpliedInstances.scala +++ b/src/main/scala/GivenInstances.scala @@ -1,10 +1,9 @@ import scala.util.{Success, Try} /** - * Implied Instances: - * - https://dotty.epfl.ch/docs/reference/contextual/instance-defs.html + * Implied Instances: https://dotty.epfl.ch/docs/reference/contextual/givens.html */ -object ImpliedInstances { +object GivenInstances { sealed trait StringParser[A] { def parse(s: String): Try[A] diff --git a/src/main/scala/Main.scala b/src/main/scala/Main.scala index d9b1e81..bae86be 100644 --- a/src/main/scala/Main.scala +++ b/src/main/scala/Main.scala @@ -1,4 +1,3 @@ - object Main { def main(args: Array[String]): Unit = { @@ -7,9 +6,9 @@ object Main { runExample("Enum Types")(EnumTypes.test) - runExample("Context Queries")(ContextQueries.test) + runExample("Context Functions")(ContextFunctions.test) - runExample("Implied Instances")(ImpliedInstances.test) + runExample("Given Instances")(GivenInstances.test) runExample("Conversion")(Conversion.test) @@ -21,7 +20,7 @@ object Main { runExample("Multiversal Equality")(MultiversalEquality.test) - runExample("Auto Param Tupling")(AutoParamTupling.test) + runExample("Parameter Untupling")(ParameterUntupling.test) runExample("Structural Types")(StructuralTypes.test) diff --git a/src/main/scala/AutoParamTupling.scala b/src/main/scala/ParameterUntupling.scala similarity index 79% rename from src/main/scala/AutoParamTupling.scala rename to src/main/scala/ParameterUntupling.scala index b72bab8..f164b40 100644 --- a/src/main/scala/AutoParamTupling.scala +++ b/src/main/scala/ParameterUntupling.scala @@ -1,11 +1,9 @@ - /** - * Automatic Tupling of Function Params: https://dotty.epfl.ch/docs/reference/other-new-features/auto-parameter-tupling.html + * Parameter Untupling: https://dotty.epfl.ch/docs/reference/other-new-features/parameter-untupling.html */ -object AutoParamTupling { +object ParameterUntupling { def test: Unit = { - /** * In order to get thread safety, you need to put @volatile before lazy vals. * https://dotty.epfl.ch/docs/reference/changed-features/lazy-vals.html @@ -19,6 +17,6 @@ object AutoParamTupling { * Consider a pattern matching anonymous function, `{ case (s, i) => ... }` */ xs.zipWithIndex.map((s, i) => println(s"$i: $s")) - } + } \ No newline at end of file diff --git a/src/main/scala/PatternMatching.scala b/src/main/scala/PatternMatching.scala index 8e64e87..e116db7 100644 --- a/src/main/scala/PatternMatching.scala +++ b/src/main/scala/PatternMatching.scala @@ -1,4 +1,3 @@ - /** * Pattern Matching: https://dotty.epfl.ch/docs/reference/changed-features/pattern-matching.html */ @@ -64,14 +63,13 @@ object PatternMatching { "even" match { case s @ Even() => println(s"$s has an even number of characters") - case s => println(s"$s has an odd number of characters") + case s => println(s"$s has an odd number of characters") } - // http://dotty.epfl.ch/docs/reference/changed/vararg-patterns.html + // http://dotty.epfl.ch/docs/reference/changed-features/vararg-patterns.html def containsConsecutive(list: List[Int]): Boolean = list match { - case List(a, b, xs: _ *) => if (a == b) true else containsConsecutive(b :: xs.toList) - case List(a, _ : _*) => false - case Nil => false + case List(a, b, xs: _*) => if (a == b) true else containsConsecutive(b :: xs.toList) + case Nil | List(_, _: _*) => false } println(containsConsecutive(List(1, 2, 3, 4, 5))) @@ -86,7 +84,7 @@ object PatternMatching { def greet(fullName: String) = fullName match { case Names(lastName, firstName, _: _*) => "Good morning, " + firstName + " " + lastName + "!" - case _ => "Welcome! Please make sure to fill in your name!" + case _ => "Welcome! Please make sure to fill in your name!" } println(greet("Alan Turing")) @@ -96,8 +94,9 @@ object PatternMatching { import namePattern._ "alice" match { case Name(n) => println(s"name is $n") - case _ => println("empty name") + case _ => println("empty name") } } + } \ No newline at end of file diff --git a/src/main/scala/StructuralTypes.scala b/src/main/scala/StructuralTypes.scala index 4eb60a4..5f117e4 100644 --- a/src/main/scala/StructuralTypes.scala +++ b/src/main/scala/StructuralTypes.scala @@ -1,4 +1,3 @@ - /** * Structural Types: https://dotty.epfl.ch/docs/reference/changed-features/structural-types.html */ From 944534d61a78f1a025249ba5df7780009c383b83 Mon Sep 17 00:00:00 2001 From: "Lan, Jian" Date: Mon, 28 Dec 2020 13:20:17 -0800 Subject: [PATCH 2/4] Simplify UnionTypes --- src/main/scala/UnionTypes.scala | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/scala/UnionTypes.scala b/src/main/scala/UnionTypes.scala index ab3e365..7dacacd 100644 --- a/src/main/scala/UnionTypes.scala +++ b/src/main/scala/UnionTypes.scala @@ -11,7 +11,7 @@ object UnionTypes { type DivisionResult = DivisionByZero | Success sealed trait List[+A] - final case class Empty() extends List[Nothing] + case object Empty extends List[Nothing] final case class Cons[+A](h: A, t: List[A]) extends List[A] private def safeDivide(a: Double, b: Double): DivisionResult = { @@ -20,11 +20,10 @@ object UnionTypes { private def either(division: Division) = division match { case DivisionByZero(m) => Left(m) - case Success(d) => Right(d) + case Success(d) => Right(d) } def test: Unit = { - val divisionResultSuccess: DivisionResult = safeDivide(4, 2) // commutative @@ -36,10 +35,10 @@ object UnionTypes { // calling `either` function with union typed value. println(either(divisionResultFailure)) - val list: Cons[Int] | Empty = Cons(1, Cons(2, Cons(3, Empty()))) - val emptyList: Empty | Cons[Any] = Empty() + val list: Cons[Int] | Empty.type = Cons(1, Cons(2, Cons(3, Empty))) + val emptyList: Empty.type | Cons[Any] = Empty println(list) println(emptyList) - } + } From d609b253d19a73e1a0e8beff4fdefdd6eae503a3 Mon Sep 17 00:00:00 2001 From: "Lan, Jian" Date: Mon, 28 Dec 2020 13:21:16 -0800 Subject: [PATCH 3/4] Adjust the format of source files to follow a consistent style --- src/main/scala/ContextFunctions.scala | 1 - src/main/scala/Conversion.scala | 2 -- src/main/scala/EnumTypes.scala | 1 - src/main/scala/GivenInstances.scala | 1 + src/main/scala/IntersectionTypes.scala | 3 +-- src/main/scala/MultiversalEquality.scala | 2 +- src/main/scala/PatternMatching.scala | 2 -- src/main/scala/StructuralTypes.scala | 1 + src/main/scala/TraitParams.scala | 2 +- src/main/scala/TypeLambdas.scala | 1 - 10 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/main/scala/ContextFunctions.scala b/src/main/scala/ContextFunctions.scala index 0028fac..0d481ad 100644 --- a/src/main/scala/ContextFunctions.scala +++ b/src/main/scala/ContextFunctions.scala @@ -35,7 +35,6 @@ object ContextFunctions { } def test: Unit = { - import ExecutionContext.Implicits.global context.asyncSum(3, 4).foreach(println) context.asyncMult(3, 4).foreach(println) diff --git a/src/main/scala/Conversion.scala b/src/main/scala/Conversion.scala index 440d70a..bee37b1 100644 --- a/src/main/scala/Conversion.scala +++ b/src/main/scala/Conversion.scala @@ -32,6 +32,4 @@ object Conversion { println(convert(new IntWrapper(42))) } - - } diff --git a/src/main/scala/EnumTypes.scala b/src/main/scala/EnumTypes.scala index 7996626..a3c34c0 100644 --- a/src/main/scala/EnumTypes.scala +++ b/src/main/scala/EnumTypes.scala @@ -24,7 +24,6 @@ object EnumTypes { } def test: Unit = { - val emptyList = ListEnum.Empty val list = ListEnum.Cons(1, ListEnum.Cons(2, ListEnum.Cons(3, ListEnum.Empty))) println(emptyList) diff --git a/src/main/scala/GivenInstances.scala b/src/main/scala/GivenInstances.scala index 0fecd99..d7f58e4 100644 --- a/src/main/scala/GivenInstances.scala +++ b/src/main/scala/GivenInstances.scala @@ -35,4 +35,5 @@ object GivenInstances { println(implicitly[StringParser[Option[Int]]](StringParser.optionParser[Int]).parse("42")) } + } diff --git a/src/main/scala/IntersectionTypes.scala b/src/main/scala/IntersectionTypes.scala index 9ebeed4..08db38f 100644 --- a/src/main/scala/IntersectionTypes.scala +++ b/src/main/scala/IntersectionTypes.scala @@ -21,7 +21,6 @@ object IntersectionTypes { } def test: Unit = { - def euclideanDistance(p1: X & Y, p2: X & Y) = { Math.sqrt(Math.pow(p2.y - p1.y, 2) + Math.pow(p2.x - p1.x, 2)) } @@ -29,6 +28,6 @@ object IntersectionTypes { val p1: P = Point(3, 4) val p2: PP = Point(6, 8) println(euclideanDistance(p1, p2)) - } + } diff --git a/src/main/scala/MultiversalEquality.scala b/src/main/scala/MultiversalEquality.scala index 4cd65f7..6ff6f72 100644 --- a/src/main/scala/MultiversalEquality.scala +++ b/src/main/scala/MultiversalEquality.scala @@ -7,7 +7,6 @@ import scala.language.strictEquality object MultiversalEquality { def test: Unit = { - // Values of types Int and String cannot be compared with == or !=, // unless we add the derived delegate instance like: given CanEqual[Int, String] = CanEqual.derived @@ -35,4 +34,5 @@ object MultiversalEquality { println(a != b) println(b == a) } + } diff --git a/src/main/scala/PatternMatching.scala b/src/main/scala/PatternMatching.scala index e116db7..9f36366 100644 --- a/src/main/scala/PatternMatching.scala +++ b/src/main/scala/PatternMatching.scala @@ -58,7 +58,6 @@ object PatternMatching { } def test: Unit = { - import booleanPattern._ "even" match { @@ -96,7 +95,6 @@ object PatternMatching { case Name(n) => println(s"name is $n") case _ => println("empty name") } - } } \ No newline at end of file diff --git a/src/main/scala/StructuralTypes.scala b/src/main/scala/StructuralTypes.scala index 5f117e4..121f7dc 100644 --- a/src/main/scala/StructuralTypes.scala +++ b/src/main/scala/StructuralTypes.scala @@ -24,4 +24,5 @@ object StructuralTypes { // age field is java.util.NoSuchElementException: None.get //println(invalidPerson.age) } + } \ No newline at end of file diff --git a/src/main/scala/TraitParams.scala b/src/main/scala/TraitParams.scala index 5d44099..00120fd 100644 --- a/src/main/scala/TraitParams.scala +++ b/src/main/scala/TraitParams.scala @@ -11,11 +11,11 @@ object TraitParams { private def printMessages(msgs: (A | B)*) = println(msgs.map(_.msg).mkString(" ")) def test: Unit = { - printMessages(new A, new B) // Sanity check the classpath: this won't run if the dotty jar is not present. val x: Int => Int = z => z x(1) } + } diff --git a/src/main/scala/TypeLambdas.scala b/src/main/scala/TypeLambdas.scala index bcbb5b8..ad160ef 100644 --- a/src/main/scala/TypeLambdas.scala +++ b/src/main/scala/TypeLambdas.scala @@ -8,7 +8,6 @@ object TypeLambdas { type Tuple = [X] =>> (X, X) def test: Unit = { - val m: T[String, Int] = Map(1 -> "1") println(m) From 88d3f9b199d1a54d3c5c3f7eeb023e2f4c964191 Mon Sep 17 00:00:00 2001 From: "Lan, Jian" Date: Tue, 29 Dec 2020 02:05:16 -0800 Subject: [PATCH 4/4] Replace implicitly with summon --- src/main/scala/ContextFunctions.scala | 2 +- src/main/scala/GivenInstances.scala | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/scala/ContextFunctions.scala b/src/main/scala/ContextFunctions.scala index 0d481ad..2999e3a 100644 --- a/src/main/scala/ContextFunctions.scala +++ b/src/main/scala/ContextFunctions.scala @@ -23,7 +23,7 @@ object ContextFunctions { type Parseable[T] = GivenInstances.StringParser[T] ?=> Try[T] def sumStrings(x: String, y: String): Parseable[Int] = { - val parser = implicitly[GivenInstances.StringParser[Int]] + val parser = summon[GivenInstances.StringParser[Int]] val tryA = parser.parse(x) val tryB = parser.parse(y) diff --git a/src/main/scala/GivenInstances.scala b/src/main/scala/GivenInstances.scala index d7f58e4..2c4a111 100644 --- a/src/main/scala/GivenInstances.scala +++ b/src/main/scala/GivenInstances.scala @@ -29,11 +29,11 @@ object GivenInstances { } def test: Unit = { - println(implicitly[StringParser[Option[Int]]].parse("21")) - println(implicitly[StringParser[Option[Int]]].parse("")) - println(implicitly[StringParser[Option[Int]]].parse("21a")) + println(summon[StringParser[Option[Int]]].parse("21")) + println(summon[StringParser[Option[Int]]].parse("")) + println(summon[StringParser[Option[Int]]].parse("21a")) - println(implicitly[StringParser[Option[Int]]](StringParser.optionParser[Int]).parse("42")) + println(summon[StringParser[Option[Int]]](using StringParser.optionParser[Int]).parse("42")) } }