Contains interpreters to enable !-notation for keywords.Monadic and other keywords in code blocks whose type support cats.FlatMap and cats.MonadError.
Contains interpreters to enable !-notation for Monadic and other keywords in code blocks whose type support scalaz.Bind, scalaz.MonadError and scalaz.MonadTrans.
Contains interpreters to enable !-notation for Monadic and other keywords in code blocks whose type support scalaz.Bind, scalaz.MonadError and scalaz.MonadTrans.
杨博 (Yang Bo)
scalaz.Free.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_.scalaz.Trampoline import _root_.scalaz.Free.Trampoline import com.thoughtworks.dsl.keywords.Monadic._ import com.thoughtworks.dsl.domains.scalaz._ 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 scalaz.syntax:
def scalazSyntaxSquare = trampoline3.flatMap { tmp1 => trampoline3.flatMap { tmp2 => Trampoline.delay { s"This string is produced by a trampoline: ${tmp1 * tmp2}" } } } scalazSyntaxSquare.run should be("This string is produced by a trampoline: 9")
@reset
code block can contain try
/ catch
/ finally
if the monadic data type supports scalaz.MonadError.
tryt.scala is a monad transformer that provides
scalaz.MonadError,
therefore try
/ catch
/ finally
expressions can be used inside a @reset
code block
whose return type is TryT[Trampoline, ?]
.import com.thoughtworks.tryt.invariant.TryT, TryT._ import scala.util.{Try, Success} type TryTTransfomredTrampoline[A] = TryT[Trampoline, A] val trampolineSuccess0: TryTTransfomredTrampoline[Int] = TryT(Trampoline.done(Try(0))) def dslTryCatch: TryTTransfomredTrampoline[String] = TryT(Trampoline.delay(Try { try { s"Division result: ${!trampoline3 / !trampolineSuccess0}" } catch { case e: ArithmeticException => s"Cannot divide ${!trampoline3} by ${!trampolineSuccess0}" } })): @reset inside(dslTryCatch) { case TryT(trampoline) => trampoline.run should be(Success("Cannot divide 3 by 0")) }
Note that !-notation can be used on
both trampoline3
and trampolineSuccess0
even when they are different types,
i.e. trampoline3
is a vanilla Trampoline,
while trampolineSuccess0
is a TryT-transfomred
Trampoline.
It is possible because the interpreters of the keywords.Monadic invoke
scalaz.MonadTrans.liftM automatically.
The above dslTryCatch
method is equivalent to the following code in scalaz.syntax:
def scalazSyntaxTryCatch: TryTTransfomredTrampoline[String] = { import _root_.scalaz.syntax.monadError._ trampoline3.liftM[TryT].flatMap { tmp0 => trampolineSuccess0.flatMap { tmp1 => TryT(Trampoline.delay(Try(s"Division result: ${tmp0 / tmp1}"))) } }.handleError { case e: ArithmeticException => trampoline3.liftM[TryT].flatMap { tmp2 => trampolineSuccess0.flatMap { tmp3 => TryT(Trampoline.delay(Try(s"Cannot divide ${tmp2} by ${tmp3}"))) } } case e => e.raiseError[TryTTransfomredTrampoline, String] } } inside(scalazSyntaxTryCatch) { case TryT(trampoline) => trampoline.run should be(Success("Cannot divide 3 by 0")) }
杨博 (Yang Bo)
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: