Skip to content

Commit 5c94852

Browse files
Merge branch 'master' into brings-new-pgp-keys
2 parents 06e4775 + c6cd0a9 commit 5c94852

File tree

5 files changed

+32
-20
lines changed

5 files changed

+32
-20
lines changed

src/main/scala/stdlib/ByNameParameter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ object ByNameParameter extends FlatSpec with Matchers with org.scalaexercises.de
1111
def takesUnitByNameParameter(res0: Either[Throwable, Int]) {
1212
def calc(x: () Int): Either[Throwable, Int] = {
1313
try {
14-
Right(x()) //An explicit call the x function
14+
Right(x()) //An explicit call of the x function
1515
} catch {
1616
case b: Throwable Left(b)
1717
}

src/main/scala/stdlib/CaseClasses.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ object CaseClasses extends FlatSpec with Matchers with org.scalaexercises.defini
2929
*
3030
* {{{
3131
* val x = Var("x")
32-
* Console.println(x.name)
32+
* println(x.name)
3333
* }}}
3434
*
3535
* For every case class the Scala compiler generates `equals` method which implements structural equality and a`toString` method. For instance:
@@ -61,7 +61,7 @@ object CaseClasses extends FlatSpec with Matchers with org.scalaexercises.defini
6161
* print("^" + x + ".")
6262
* printTerm(b)
6363
* case App(f, v) =>
64-
* Console.print("(")
64+
* print("(")
6565
* printTerm(f)
6666
* print(" ")
6767
* printTerm(v)

src/main/scala/stdlib/Classes.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ object Classes extends FlatSpec with Matchers with org.scalaexercises.definition
3131
*
3232
* The program defines an executable application `Classes` in form of a top-level singleton object with a `main` method. The `main` method creates a new `Point` and stores it in value `pt`.
3333
*
34+
* This also demonstrates the use of a value parameters in ClassWithValParameter(val name: String), which automatically creates an internal property (val name: String) in the class.
35+
*
3436
*/
3537
def classWithValParameterClasses(res0: String) {
3638
class ClassWithValParameter(val name: String)

src/main/scala/stdlib/TypeVariance.scala

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -99,25 +99,26 @@ object TypeVariance extends FlatSpec with Matchers with org.scalaexercises.defin
9999
}
100100

101101
/** Declaring - indicates contravariance variance. Using - you can apply any container with a certain type to a container with a superclass of that type. This is reverse to covariant. In our example, we can set a citrus basket to an orange or tangelo basket. Since an orange or tangelo basket are a citrus basket. Contravariance is the opposite of covariance:
102-
* //TODO rework without mutability
103-
*
104-
* def contravarianceVarianceTypeVariance(res0: String, res1: String, res2: String, res3: String) {
105-
* class MyContainer[-A](val a: A)(implicit manifest: scala.reflect.Manifest[A]) {
106-
* def contents = manifest.runtimeClass.getSimpleName
107-
* }
108-
*
109-
* val citrusBasket: MyContainer[Citrus] = new MyContainer[Citrus](new Orange)
110-
* citrusBasket.contents should be(res0)
111-
* val orangeBasket: MyContainer[Orange] = new MyContainer[Citrus](new Tangelo)
112-
* orangeBasket.contents should be(res1)
113-
* val tangeloBasket: MyContainer[Tangelo] = new MyContainer[Citrus](new Orange)
114-
* tangeloBasket.contents should be(res2)
115-
*
116-
* val orangeBasketReally: MyContainer[Orange] = tangeloBasket.asInstanceOf[MyContainer[Orange]]
117-
* orangeBasketReally.contents should be(res3)
118-
* }
119102
*/
120103

104+
def contravarianceVarianceTypeVariance(res0: String, res1: String, res2: String, res3: String) {
105+
class MyContainer[-A](a: A)(implicit manifest: scala.reflect.Manifest[A]) { //Can't receive a val because it would be in a covariant position
106+
def contents = manifest.runtimeClass.getSimpleName
107+
}
108+
109+
val citrusBasket: MyContainer[Citrus] = new MyContainer[Citrus](new Orange)
110+
citrusBasket.contents should be(res0)
111+
val orangeBasket: MyContainer[Orange] = new MyContainer[Citrus](new Tangelo)
112+
orangeBasket.contents should be(res1)
113+
val tangeloBasket: MyContainer[Tangelo] = new MyContainer[Citrus](new Orange)
114+
tangeloBasket.contents should be(res2)
115+
val bananaBasket: MyContainer[Banana] = new MyContainer[Fruit](new Apple)
116+
bananaBasket.contents should be(res3)
117+
118+
//val fruitBasket: MyContainer[Fruit] = new MyContainer[Citrus](new Orange) //Bad!
119+
//val wrongCitrusBasket: MyContainer[Citrus] = new MyContainer[Orange](new Orange) //Bad!
120+
}
121+
121122
/** Declaring neither `-`/`+`, indicates invariance variance. You cannot use a superclass variable reference (\"contravariant\" position) or a subclass variable reference (\"covariant\" position) of that type. In our example, this means that if you create a citrus basket you can only reference that citrus basket with a citrus variable only.
122123
*
123124
* Invariance means you need to specify the type exactly:

src/test/scala/stdlib/TypeVarianceSpec.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ class TypeVarianceSpec extends Spec with Checkers {
5252
)
5353
}
5454

55+
def `contravariance` = {
56+
check(
57+
Test.testSuccess(
58+
TypeVariance.contravarianceVarianceTypeVariance _,
59+
"Citrus" :: "Citrus" :: "Citrus" :: "Fruit" :: HNil
60+
)
61+
)
62+
}
63+
5564
def `invariance` = {
5665
check(
5766
Test.testSuccess(

0 commit comments

Comments
 (0)