scalaz

object scalaz

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.keywords.Monadic.given
        import com.thoughtworks.dsl.domains.scalaz.given
        import com.thoughtworks.dsl.bangnotation._
        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")
    <hr/>
    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"))
        }
class Object
trait Matchable
class Any

Type members

Classlikes

abstract
class ScalazTransformerDsl[F[_], G[_], A, B] extends Dsl[Monadic[F, A], G[B], A]

Implicits

Implicits

implicit
def scalazLift[F[_], A, B](implicit applicative: Applicative[F]): OneStep[A, F[A]]
implicit
def scalazMonadTransformerDsl0[F[_[_], _], G[_], A, B](implicit monadTrans: MonadTrans[F], monad0: Monad[G]): ScalazTransformerDsl[G, [X] =>> F[G, X], A, B]
implicit
def scalazMonadTransformerDsl1[F[_[_], _], H[_], G[_], A, B](implicit monadTrans: MonadTrans[F], rest: ScalazTransformerDsl[H, G, A, B]): ScalazTransformerDsl[H, [X] =>> F[G, X], A, B]
implicit
def scalazMonadicDsl[F[_], A, B](implicit bind: Bind[F]): Dsl[Monadic[F, A], F[B], A]
implicit
def scalazTryCatch[F[_], A, B](implicit monadError: MonadThrowable[F]): TryCatch[A, F[B], F[A]]
implicit
def scalazTryFinally[F[_], A, B](implicit monadError: MonadThrowable[F]): TryFinally[A, F[B], F[A], F[Unit]]