Skip to content

Commit 6ec3feb

Browse files
committed
formatting changes
1 parent 4c76380 commit 6ec3feb

File tree

3 files changed

+91
-70
lines changed

3 files changed

+91
-70
lines changed

scala-core-modules/scala-core-fp/src/main/scala/com/baeldung/scala/freemonad/FreeMonads.scala

Lines changed: 88 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@ trait Monad[F[_]]:
1717

1818
// List composition example:
1919

20-
lazy val listComposition =
21-
for
22-
number <- 0 to 9
23-
letter <- 'A' to 'Z'
20+
lazy val listComposition =
21+
for
22+
number <- 0 to 9
23+
letter <- 'A' to 'Z'
2424
yield s"$number$letter"
2525

2626
// Which the compiler transforms to:
2727

2828
lazy val desugaredListComposition =
29-
(0 to 9).flatMap: number =>
30-
('A' to 'Z').map: letter =>
29+
(0 to 9).flatMap: number =>
30+
('A' to 'Z').map: letter =>
3131
s"$number$letter"
3232

3333
// A functor is simpler and less powerful than a monad:
@@ -37,13 +37,14 @@ trait Functor[F[_]]:
3737

3838
// A transformation between two higher-kinded types with the same type parameter:
3939

40-
trait ~>[F[_], G[_]]:
40+
trait ~>[F[_], G[_]]:
4141
def apply[A: Typeable](f: F[A]): G[A]
4242

4343
// Free allows us to lift a functor with monadic composition as a data structure:
4444

45-
sealed trait Free[F[_], A: Typeable]:
46-
def map[B: Typeable](f: A => B): Free[F, B] = FlatMap(this, (a: A) => Pure(f(a)))
45+
sealed trait Free[F[_], A: Typeable]:
46+
def map[B: Typeable](f: A => B): Free[F, B] =
47+
FlatMap(this, (a: A) => Pure(f(a)))
4748
def flatMap[B: Typeable](f: A => Free[F, B]): Free[F, B] = FlatMap(this, f)
4849

4950
def foldMapAs[G[_]: Monad](using F ~> G): G[A] = this match
@@ -54,8 +55,11 @@ sealed trait Free[F[_], A: Typeable]:
5455
f(in).foldMapAs[G]
5556
case Suspend(s) => summon[F ~> G](s)
5657

57-
final case class Pure[F[_], A: Typeable](value: A) extends Free[F, A]
58-
final case class FlatMap[F[_], A: Typeable, B: Typeable](sub: Free[F, A], f: A => Free[F, B]) extends Free[F, B]
58+
final case class Pure[F[_], A: Typeable](value: A) extends Free[F, A]
59+
final case class FlatMap[F[_], A: Typeable, B: Typeable](
60+
sub: Free[F, A],
61+
f: A => Free[F, B]
62+
) extends Free[F, B]
5963
final case class Suspend[F[_], A: Typeable](s: F[A]) extends Free[F, A]
6064

6165
// We define a non-monadic type:
@@ -66,65 +70,73 @@ trait LazyCatchable[+A]:
6670
final class Lazy[A](value: => A) extends LazyCatchable[A]:
6771
def run(): Either[Catch, A] = Try(value) match
6872
case Success(value) => Right(value)
69-
case Failure(e) => Left(Catch(e))
73+
case Failure(e) => Left(Catch(e))
7074

7175
final case class Catch(e: Throwable) extends LazyCatchable[Nothing]:
7276
def run(): Either[Catch, Nothing] = Left(this)
7377

7478
// We can write monadic programs with it:
7579

76-
lazy val sumProgram: Free[LazyCatchable, Int] =
77-
for
78-
a <- Suspend(Lazy(1))
79-
b <- Suspend(Lazy(2))
80-
result <- Pure(a + b)
80+
lazy val sumProgram: Free[LazyCatchable, Int] =
81+
for
82+
a <- Suspend(Lazy(1))
83+
b <- Suspend(Lazy(2))
84+
result <- Pure(a + b)
8185
yield result
8286

8387
// Which is translated by the compiler to this:
8488

8589
lazy val desugaredSumProgram =
8690
FlatMap(
87-
Suspend(Lazy(1)),
88-
(num1: Int) => FlatMap(
89-
Suspend(Lazy(2)),
90-
(num2: Int) => Pure(num1 + num2)
91-
)
91+
Suspend(Lazy(1)),
92+
(num1: Int) =>
93+
FlatMap(
94+
Suspend(Lazy(2)),
95+
(num2: Int) => Pure(num1 + num2)
96+
)
9297
)
9398

9499
// We provide a ~> to a Future:
95100

96101
given LazyCatchable2Future: (LazyCatchable ~> Future) with
97102
def apply[A: Typeable](f: LazyCatchable[A]): Future[A] = f match
98103
case Catch(e) => Future.failed(e)
99-
case lazyValue: Lazy[_] => Future:
100-
lazyValue.run() match
101-
case Left(Catch(e)) => throw e
102-
case Right(value: A @unchecked) => value
104+
case lazyValue: Lazy[_] =>
105+
Future:
106+
lazyValue.run() match
107+
case Left(Catch(e)) => throw e
108+
case Right(value: A @unchecked) => value
103109

104110
// We define a Monad instance for Future:
105111

106-
given FutureMonad: Monad[Future] with
107-
def flatMap[A, B](fa: Future[A])(f: (A) => Future[B]): Future[B] = fa.flatMap(f)
112+
given FutureMonad: Monad[Future] with
113+
def flatMap[A, B](fa: Future[A])(f: (A) => Future[B]): Future[B] =
114+
fa.flatMap(f)
108115

109-
def pure[A](a: A): Future[A] = Future(a)
116+
def pure[A](a: A): Future[A] = Future(a)
110117

111118
override def map[A, B](fa: Future[A])(f: A => B): Future[B] = fa.map(f)
112119

113120
// We can then convert our sumProgram to a Future:
114121

115-
lazy val sumProgramFuture: Future[Int] = sumProgram.foldMapAs[Future](using FutureMonad, LazyCatchable2Future) // Future computes to 3
122+
lazy val sumProgramFuture: Future[Int] = sumProgram.foldMapAs[Future](using
123+
FutureMonad,
124+
LazyCatchable2Future
125+
) // Future computes to 3
116126

117127
// Let's consider a more advanced workflow DSL:
118128

119-
enum WorkflowCommand:
129+
enum WorkflowCommand:
120130
case FeelInspiredToLearn
121131
case LikeFriendlyEnvironments
122132
case WantToHelpPeopleBuildConfidenceCoding
123133
case JoinBaeldungAsAWriter
124134

125135
// We can then define our logic:
126136

127-
def command[C <: WorkflowCommand](c: => C): Free[LazyCatchable, C] = Suspend(Lazy(c))
137+
def command[C <: WorkflowCommand](c: => C): Free[LazyCatchable, C] = Suspend(
138+
Lazy(c)
139+
)
128140

129141
lazy val joinBaeldungWorkflow: Free[LazyCatchable, WorkflowCommand] =
130142
for
@@ -137,46 +149,55 @@ lazy val joinBaeldungWorkflow: Free[LazyCatchable, WorkflowCommand] =
137149
// Then we define a translation to Future:
138150

139151
given BaeldungWorkflowInterpreter: (LazyCatchable ~> Future) with
140-
private def askQuestion(question: String, repeat: Boolean = false): Boolean =
141-
if repeat then print(s"\nInvalid response: try again (y or n) ")
142-
else print(s"\n$question (y or n) ")
143-
144-
readChar() match
145-
case 'y' | 'Y' => true
146-
case 'n' | 'N' => false
147-
case _ => askQuestion(question, true)
148-
149-
private def step[C <: WorkflowCommand](question: String, command: C, error: String): Future[C] = Future:
152+
private def askQuestion(question: String, repeat: Boolean = false): Boolean =
153+
if repeat then print(s"\nInvalid response: try again (y or n) ")
154+
else print(s"\n$question (y or n) ")
155+
156+
readChar() match
157+
case 'y' | 'Y' => true
158+
case 'n' | 'N' => false
159+
case _ => askQuestion(question, true)
160+
161+
private def step[C <: WorkflowCommand](
162+
question: String,
163+
command: C,
164+
error: String
165+
): Future[C] = Future:
150166
if askQuestion(question) then command
151167
else throw new Exception(error)
152168

153169
def apply[A: Typeable](f: LazyCatchable[A]): Future[A] = f match
154170
case Catch(e) => Future.failed(e)
155-
case lazyCmd: Lazy[_] => lazyCmd.run() match
156-
case Left(Catch(e)) => Future.failed(e)
157-
case Right(command: WorkflowCommand) =>
158-
command match
159-
case WorkflowCommand.FeelInspiredToLearn =>
160-
step(
161-
question = "Do you feel inspired to learn Scala?",
162-
command = command,
163-
error = "Baeldung has tutorials for other technologies too, like Java."
164-
)
165-
case WorkflowCommand.LikeFriendlyEnvironments =>
166-
step(
167-
question = "Do you like friendly environments?",
168-
command = command,
169-
error = "Bye."
170-
)
171-
case WorkflowCommand.WantToHelpPeopleBuildConfidenceCoding =>
172-
step(
173-
question = "Do you want to help people build confidence coding?",
174-
command = command,
175-
error = "Baeldung tutorials are reliable and informative."
176-
)
177-
case WorkflowCommand.JoinBaeldungAsAWriter => Future.successful(command)
178-
case Right(misc) => Future.successful(misc)
171+
case lazyCmd: Lazy[_] =>
172+
lazyCmd.run() match
173+
case Left(Catch(e)) => Future.failed(e)
174+
case Right(command: WorkflowCommand) =>
175+
command match
176+
case WorkflowCommand.FeelInspiredToLearn =>
177+
step(
178+
question = "Do you feel inspired to learn Scala?",
179+
command = command,
180+
error =
181+
"Baeldung has tutorials for other technologies too, like Java."
182+
)
183+
case WorkflowCommand.LikeFriendlyEnvironments =>
184+
step(
185+
question = "Do you like friendly environments?",
186+
command = command,
187+
error = "Bye."
188+
)
189+
case WorkflowCommand.WantToHelpPeopleBuildConfidenceCoding =>
190+
step(
191+
question =
192+
"Do you want to help people build confidence coding?",
193+
command = command,
194+
error = "Baeldung tutorials are reliable and informative."
195+
)
196+
case WorkflowCommand.JoinBaeldungAsAWriter =>
197+
Future.successful(command)
198+
case Right(misc) => Future.successful(misc)
179199

180200
// The translation is then very simple and intuitive:
181201

182-
lazy val joinBaeldung: Future[WorkflowCommand] = joinBaeldungWorkflow.foldMapAs[Future](using FutureMonad, BaeldungWorkflowInterpreter)
202+
lazy val joinBaeldung: Future[WorkflowCommand] = joinBaeldungWorkflow
203+
.foldMapAs[Future](using FutureMonad, BaeldungWorkflowInterpreter)

scala-core-modules/scala-core-fp/src/main/scala/com/baeldung/scala/freemonad/InteractiveInterpretation.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ package com.baeldung.scala.freemonad
33
// import scala.concurrent.Await
44
// import scala.concurrent.duration.*
55

6-
// @main def runWorkflow(): Unit =
6+
// @main def runWorkflow(): Unit =
77
// val result = Await.result(joinBaeldung, 100.seconds)
8-
// println(result)
8+
// println(result)

scala-core-modules/scala-core-fp/src/test/scala/com/baeldung/scala/freemonad/FreeMonadUnitTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@ class FreeMonadUnitTest
2929
"joinBaeldungWorkflows spec should succeed" in:
3030
joinBaeldungWorkflow
3131
.foldMapAs[Future](using FutureMonad, LazyCatchable2Future)
32-
.map(_ shouldBe WorkflowCommand.JoinBaeldungAsAWriter)
32+
.map(_ shouldBe WorkflowCommand.JoinBaeldungAsAWriter)

0 commit comments

Comments
 (0)