Skip to content

Commit 8457000

Browse files
Merge branch 'master' of github.com:baeldung/scala-tutorials into SCALA-24
2 parents 67e93c4 + 3d1cec8 commit 8457000

File tree

8 files changed

+335
-0
lines changed

8 files changed

+335
-0
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.baeldung.scala
2+
3+
import scala.concurrent.ExecutionContext.Implicits.global
4+
import scala.concurrent._
5+
import scala.concurrent.duration._
6+
7+
class LazyVal {
8+
9+
var age = 27
10+
11+
lazy val getMemberNo = {
12+
age = age + 1
13+
8
14+
}
15+
}
16+
17+
object FirstObj {
18+
lazy val initialState = 42
19+
lazy val start = SecondObj.initialState
20+
}
21+
22+
object SecondObj {
23+
lazy val initialState = FirstObj.initialState
24+
}
25+
26+
object Deadlock extends App {
27+
def run = {
28+
val result = Future.sequence(Seq(
29+
Future {
30+
FirstObj.start
31+
},
32+
Future {
33+
SecondObj.initialState
34+
}))
35+
Await.result(result, 10.second)
36+
}
37+
38+
run
39+
}
40+
41+
object LazyValStore {
42+
43+
lazy val squareOf5 = square(5)
44+
lazy val squareOf6 = square(6)
45+
46+
def square(n: Int): Int = n * n
47+
}
48+
49+
object SequentialLazyVals extends App {
50+
def run = {
51+
val futures = Future.sequence(Seq(
52+
Future {
53+
LazyValStore.squareOf5
54+
},
55+
Future {
56+
LazyValStore.squareOf6
57+
}))
58+
Await.result(futures, 5.second)
59+
}
60+
61+
run.foreach(println)
62+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.baeldung.scala
2+
3+
class User(val name: String, val age: Int)
4+
5+
object User {
6+
def apply(name: String, age: Int) = new User(name, age)
7+
8+
def apply(name: String) = new User(name, 0)
9+
10+
def unapply(u: User): Option[(String, Int)] = Some(u.name, u.age)
11+
}
12+
13+
object UserMainApp extends App {
14+
val user1: User = new User("John", 25)
15+
val user2: User = User.apply("John", 25)
16+
val user3: User = User("John", 25)
17+
18+
val userArgs: Option[(String, Int)] = User.unapply(user1)
19+
20+
user1 match {
21+
case User(_, age) if age < 18 =>
22+
println("You are not allowed to get a driver license.")
23+
case User(_, age) if age >= 18 =>
24+
println("You are allowed to get a driver's license.")
25+
}
26+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.baeldung.scala.partialfunctions
2+
3+
object SquareRoot {
4+
val squareRoot = new PartialFunction[Double, Double] {
5+
def apply(x: Double) = Math.sqrt(x)
6+
def isDefinedAt(x: Double) = x >= 0
7+
}
8+
9+
val squareRootImplicit: PartialFunction[Double, Double] = {
10+
case x if x >= 0 => Math.sqrt(x)
11+
}
12+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.baeldung.scala.partialfunctions
2+
3+
object SwapIntegerSign {
4+
5+
private val negativeOrZeroToPositive: PartialFunction[Int, Int] = {
6+
case x if x <= 0 => Math.abs(x)
7+
}
8+
9+
private val positiveToNegative: PartialFunction[Int, Int] = {
10+
case x if x > 0 => -1 * x
11+
}
12+
13+
val swapSign: PartialFunction[Int, Int] = {
14+
positiveToNegative orElse negativeOrZeroToPositive
15+
}
16+
17+
val printIfPositive: PartialFunction[Int, Unit] = {
18+
case x if x > 0 => println(s"$x is positive!")
19+
}
20+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.baeldung.scala
2+
3+
import org.scalatest.FunSuite
4+
import org.scalatest.Matchers._
5+
6+
import scala.concurrent.ExecutionContext.Implicits.global
7+
import scala.concurrent.duration._
8+
import scala.concurrent.{Future, _}
9+
import com.baeldung.scala
10+
11+
class LazyValUnitTest extends FunSuite {
12+
13+
test("lazy val is computed only once") {
14+
//given
15+
val lazyVal = new LazyVal
16+
lazyVal.getMemberNo //initialize the lazy val
17+
lazyVal.age shouldBe 28
18+
19+
//when
20+
lazyVal.getMemberNo
21+
22+
//then
23+
lazyVal.age shouldBe 28
24+
}
25+
26+
test("lazy vals should execute sequentially in an instance ") {
27+
//given
28+
val futures = Future.sequence(Seq(
29+
Future {
30+
scala.LazyValStore.squareOf5
31+
},
32+
Future {
33+
scala.LazyValStore.squareOf6
34+
}))
35+
36+
//when
37+
val result = Await.result(futures, 5.second)
38+
39+
//then
40+
result should contain(25)
41+
result should contain(36)
42+
}
43+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package com.baeldung.scala.currying
2+
3+
import org.junit.Test
4+
import org.scalatest.Matchers
5+
6+
class CurryingUnitTest extends Matchers {
7+
8+
@Test
9+
def givenMultipleArgumentsFunction_whenCurried_thenReturnCurriedFunction() {
10+
val sum: (Int, Int) => Int = (x, y) => x + y
11+
val curriedSum: Int => Int => Int = sum.curried
12+
13+
sum(1, 2) shouldBe 3
14+
curriedSum(1)(2) shouldBe 3
15+
}
16+
17+
@Test
18+
def givenMultipleArgumentsMethod_whenCurried_thenReturnCurriedFunction() {
19+
def sum(x: Int, y: Int): Int = x + y
20+
21+
val curriedSum: Int => Int => Int = (sum _).curried
22+
23+
sum(1, 2) shouldBe 3
24+
curriedSum(1)(2) shouldBe 3
25+
}
26+
27+
@Test
28+
def givenMultipleArgumentListsMethod_whenCurried_thenReturnCurriedFunction() {
29+
def sum(x: Int)(y: Int): Int = x + y
30+
31+
val curriedSum: Int => Int => Int = sum
32+
33+
sum(1)(2) shouldBe 3
34+
curriedSum(1)(2) shouldBe 3
35+
}
36+
37+
@Test
38+
def givenCurriedFunction_whenPartialApplied_thenReturnLowerArityFunction() {
39+
val sum: Int => Int => Int = x => y => x + y
40+
val increment: Int => Int = sum(1)
41+
42+
increment(1) shouldBe 2
43+
}
44+
45+
@Test
46+
def givenMultipleArgumentListsMethod_whenPartialApplied_thenReturnLowerArityMethod() {
47+
def sum(x: Int)(y: Int): Int = x + y
48+
49+
val increment: Int => Int = sum(1)
50+
51+
increment(1) shouldBe 2
52+
}
53+
54+
@Test
55+
def givenMultipleArgumentsFindMethod_whenCalled_thenPredicateFunctionNeedsExplicitType() {
56+
def find[A](xs: List[A], predicate: A => Boolean): Option[A] = {
57+
xs match {
58+
case Nil => None
59+
case head :: tail =>
60+
if (predicate(head)) Some(head) else find(tail, predicate)
61+
}
62+
}
63+
64+
find(List(1, 2, 3), (x: Int) => x % 2 == 0) shouldBe Some(2)
65+
}
66+
67+
@Test
68+
def givenMultipleArgumentListFindMethod_whenCalled_thenPredicateFunctionDoesNotNeedExplicitType() {
69+
def find[A](xs: List[A])(predicate: A => Boolean): Option[A] = {
70+
xs match {
71+
case Nil => None
72+
case head :: tail =>
73+
if (predicate(head)) Some(head) else find(tail)(predicate)
74+
}
75+
}
76+
77+
find(List(1, 2, 3))(x => x % 2 == 0) shouldBe Some(2)
78+
}
79+
80+
@Test
81+
def givenGenericMultipleArgumentListSumMethod_whenPartialApplied_thenReturnSimpleMethods() {
82+
def sumF(f: Int => Int)(x: Int, y: Int): Int = f(x) + f(y)
83+
val sum: (Int, Int) => Int = sumF(identity)
84+
val sumSquare: (Int, Int) => Int = sumF(x => x * x)
85+
val increment: Int => Int = sum.curried(1)
86+
val decrement: Int => Int = sum.curried(-1)
87+
88+
sum(1, 2) shouldBe 3
89+
sumSquare(1, 2) shouldBe 5
90+
increment(2) shouldBe 3
91+
decrement(2) shouldBe 1
92+
}
93+
94+
@Test
95+
def givenMultipleArgumentsFunction_whenUseItAsOneArgumentFunction_thenNeedsExplicitArgumentPassing() {
96+
val sum: (Int, Int) => Int = (x, y) => x + y
97+
val numbers: List[Int] = List(1, 2, 3)
98+
99+
numbers.map(n => sum(1, n)) shouldBe List(2, 3, 4)
100+
}
101+
102+
@Test
103+
def givenCurriedFunction_whenUseItAsOneArgumentFunction_thenDoesNotNeedExplicitArgumentPassing() {
104+
val curriedSum: Int => Int => Int = x => y => x + y
105+
val numbers: List[Int] = List(1, 2, 3)
106+
107+
numbers.map(curriedSum(1)) shouldBe List(2, 3, 4)
108+
}
109+
110+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.baeldung.scala.partialfunctions
2+
3+
import org.scalatest.FlatSpec
4+
5+
class SquareRootUnitTest extends FlatSpec {
6+
7+
"SquareRoot" should "return the correct value for positive double" in {
8+
assert(SquareRoot.squareRoot(4.0) == 2.0)
9+
}
10+
11+
it should "return NaN for a negative double" in {
12+
assert(SquareRoot.squareRoot(-4.0).equals(Double.NaN))
13+
}
14+
15+
"SquareRootImplicit" should "return the correct value for a positive double" in {
16+
assert(SquareRoot.squareRootImplicit(4.0) == 2.0)
17+
}
18+
19+
it should "throw a 'scala.MatchError' exception" in {
20+
assertThrows[scala.MatchError] {
21+
SquareRoot.squareRootImplicit(-4.0)
22+
}
23+
}
24+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.baeldung.scala.partialfunctions
2+
3+
import org.scalatest.FlatSpec
4+
5+
class SwapIntegerSignUnitTest extends FlatSpec {
6+
7+
"swapSign" should "return a positive number when a negative is given" in {
8+
assert(SwapIntegerSign.swapSign(-3) == 3)
9+
}
10+
11+
it should "return a negative number when a positive is given" in {
12+
assert(SwapIntegerSign.swapSign(3) == -3)
13+
}
14+
15+
"printIfPositive" should "print a positive number" in {
16+
assert(SwapIntegerSign.printIfPositive(3).getClass == classOf[Unit])
17+
}
18+
19+
it should "throw a 'scala.MatchError' exception given a negative number" in {
20+
assertThrows[scala.MatchError] {
21+
SwapIntegerSign.printIfPositive(-3)
22+
}
23+
}
24+
25+
"swapSign andThen printIfPositive" should "chain and print a positive number" in {
26+
assert(
27+
(SwapIntegerSign.swapSign andThen SwapIntegerSign.printIfPositive)(-1).getClass == classOf[
28+
Unit
29+
]
30+
)
31+
}
32+
33+
it should "chain and throw a 'scala.MatchError' exception given a negative number" in {
34+
assertThrows[scala.MatchError] {
35+
(SwapIntegerSign.swapSign andThen SwapIntegerSign.printIfPositive)(1)
36+
}
37+
}
38+
}

0 commit comments

Comments
 (0)