scalaz

object scalaz extends LowPriority0

Contains interpreters to enable !-notation for Monadic and other keywords in code blocks whose type support scalaz.Bind, scalaz.MonadError and scalaz.MonadTrans.

Authors

杨博 (Yang Bo)

Example

scalaz.Free.Trampoline is a monadic data type that performs tail call optimization. It can be built from a @[[Dsl.reset 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.given
         import com.thoughtworks.dsl.macros.Reset.Default.reset
         import com.thoughtworks.dsl.keywords.Monadic.unary_!
         val trampoline3 = Trampoline.done(3)
         def dslSquare = reset(Trampoline.delay {
           s"This string is produced by a trampoline: ${!trampoline3 * !trampoline3}"
         })
         dslSquare.run should be("This string is produced by a trampoline: 9")

!trampoline3 is a shortcut of !Monadic(trampoline3), enabled by import com.thoughtworks.dsl.keywords.Monadic.given, 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")

A `@[[Dsl.reset reset]]` code block can contain `try` / `catch` / `finally` if the monadic data type supports [[scalaz.MonadError]]. [[https://github.com/ThoughtWorksInc/tryt.scala tryt.scala]] is a monad transformer that provides [[scalaz.MonadError]], therefore `try` / `catch` / `finally` expressions can be used inside a `@[[Dsl.reset reset]]` code block whose return type is `TryT[Trampoline, ?]`. {{{ import com.thoughtworks.tryt.invariant.TryT, TryT.given import scala.util.{Try, Success} type TryTTransfomredTrampoline[A] = TryT[Trampoline, A] val trampolineSuccess0: TryTTransfomredTrampoline[Int] = TryT(Trampoline.done(Try(0))) def dslTryCatch: TryTTransfomredTrampoline[String] = reset(TryT(Trampoline.delay(Try { try { s"Division result: ${!trampoline3 / !trampolineSuccess0}" } catch { case e: ArithmeticException => s"Cannot divide ${!trampoline3} by ${!trampolineSuccess0}" } }))) inside(dslTryCatch) { case TryT(trampoline) => trampoline.run should be(Success("Cannot divide 3 by 0")) } }}} Note that [[Dsl.Keyword#unary_$bang !-notation]] can be used on both `trampoline3` and `trampolineSuccess0` even when they are different types, i.e. `trampoline3` is a vanilla [[scalaz.Free.Trampoline Trampoline]], while `trampolineSuccess0` is a [[com.thoughtworks.tryt.invariant.TryT TryT]]-transfomred [[scalaz.Free.Trampoline 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]]: {{{ import _root_.scalaz.syntax.monad._ 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")) } }}}
trait LowPriority0
class Object
trait Matchable
class Any

Givens

Givens

given DslComposer_F_A_F: DslComposer[F[B], A, F[A]]
given OneStep_G_F: Lift[From, To]
given Original_Monadic_F_A: Original[Monadic[G[A]], F[B], A]

The Dsl instance that converts a domains.Monadic keyword to the monad domain type then flatMap. This instance helps when the keyword supports a domain D that can be lifted to the F[A], while there is not general rule to derive F[A] from D. For example, when F[A] is a monad transformer and D is the underlying monad type.

The Dsl instance that converts a domains.Monadic keyword to the monad domain type then flatMap. This instance helps when the keyword supports a domain D that can be lifted to the F[A], while there is not general rule to derive F[A] from D. For example, when F[A] is a monad transformer and D is the underlying monad type.

Inherited givens

given OneStep_A_F: Lift[From, To]
Inherited from
LowPriority0
given StackUnsafe_K_F_A: StackUnsafe[K, F[B], A]

The Dsl instance that converts a keyword to the monad domain type then flatMap. This instance helps when the keyword supports a domain D that can be lifted to the F[A], while there is not general rule to derive F[A] from D. For example, when F[A] is a monad transformer and D is the underlying monad type.

The Dsl instance that converts a keyword to the monad domain type then flatMap. This instance helps when the keyword supports a domain D that can be lifted to the F[A], while there is not general rule to derive F[A] from D. For example, when F[A] is a monad transformer and D is the underlying monad type.

Inherited from
LowPriority0