A @reset code block can contain try / catch / finally
if the monadic data type supports cats.MonadError.
For example, cats.effect.IO is a monadic data type that supports cats.MonadError,
therefore try / catch / finally expressions can be used inside a @reset code block
whose return type is cats.effect.IO.
import com.thoughtworks.dsl.keywords.Monadic._
import com.thoughtworks.dsl.domains.cats._
import _root_.cats.effect.IO
import com.thoughtworks.dsl.Dsl.reset
val io0 = IO(0)
def dslTryCatch: IO[String] = IO {
try {
s"Division result: ${!io0 / !io0}"
} catch {
case e: ArithmeticException =>
s"Cannot divide ${!io0} by itself"
}
}: @reset
dslTryCatch.unsafeRunSync() should be("Cannot divide 0 by itself")
The above dslTryCatch method is equivalent to the following code in cats.syntax:
def catsSyntaxTryCatch: IO[String] = {
import _root_.cats.syntax.applicativeError._
io0.flatMap { tmp0 =>
io0.flatMap { tmp1 =>
IO(s"Division result: ${tmp0 / tmp1}")
}
}.handleErrorWith {
case e: ArithmeticException =>
io0.flatMap { tmp2 =>
IO(s"Cannot divide ${tmp2} by itself")
}
case e =>
e.raiseError[IO, String]
}
}
catsSyntaxTryCatch.unsafeRunSync() should be("Cannot divide 0 by itself")
,
Trampoline is a monadic data type that performs tail call optimization.
It can be built from a @reset code block within some !-notation,
similar to the each method in
ThoughtWorks Each.
import _root_.cats.free.Trampoline
import _root_.cats.instances.function._
import com.thoughtworks.dsl.keywords.Monadic._
import com.thoughtworks.dsl.domains.cats._
import com.thoughtworks.dsl.Dsl.reset
val trampoline3 = Trampoline.done(3)
def dslSquare = Trampoline.delay {
s"This string is produced by a trampoline: ${!trampoline3 * !trampoline3}"
}: @reset
dslSquare.run should be("This string is produced by a trampoline: 9")
!trampoline3 is a shortcut of !Monadic(trampoline3),
which will be converted to flatMap calls by our DSL interpreter.
Thus, the method dslSquare is equivalent to the following code in cats.syntax:
def catsSyntaxSquare = trampoline3.flatMap { tmp1 =>
trampoline3.flatMap { tmp2 =>
Trampoline.delay {
s"This string is produced by a trampoline: ${tmp1 * tmp2}"
}
}
}
catsSyntaxSquare.run should be("This string is produced by a trampoline: 9")
Contains interpreters to enable !-notation for keywords.Monadic and other keywords in code blocks whose type support cats.FlatMap and cats.MonadError.
Author:
杨博 (Yang Bo)
A
@reset
code block can containtry
/catch
/finally
if the monadic data type supports cats.MonadError. For example, cats.effect.IO is a monadic data type that supports cats.MonadError, thereforetry
/catch
/finally
expressions can be used inside a@reset
code block whose return type is cats.effect.IO.The above
dslTryCatch
method is equivalent to the following code in cats.syntax:Trampoline is a monadic data type that performs tail call optimization. It can be built from a
@reset
code block within some !-notation, similar to the each method in ThoughtWorks Each.!trampoline3
is a shortcut of!Monadic(trampoline3)
, which will be converted toflatMap
calls by our DSL interpreter. Thus, the methoddslSquare
is equivalent to the following code in cats.syntax: