Como vimos anteriormente, podemos crear pilas de mónadas transformadas utilizando el método de apply del transformador o la sintaxis pure :
// Create using apply:
val errorStack1 = OptionT[ErrorOr, Int](Right(Some(10)))
// errorStack1: OptionT[ErrorOr, Int] = OptionT(Right(Some(10)))
// Create using pure:
val errorStack2 = 32.pure[ErrorOrOption]
// errorStack2: ErrorOrOption[Int] = OptionT(Right(Some(32)))
Una vez que hayamos terminado con una pila de transformadores de mónadas, podemos desempaquetarla usando el método value. Esto devuelve la pila sin transformar. Entonces podemos manipular las mónadas individuales de la manera habitual:
// Extracting the untransformed monad stack:
errorStack1.value
// res4: ErrorOr[Option[Int]] = Right(Some(10))
// Mapping over the Either in the stack:
errorStack2.value.map(_.getOrElse(-1))
// res5: Either[String, Int] = Right(32)
Cada llamada a value desempaqueta un solo transformador de mónada. Es posible que necesitemos más de una llamada para descomprimir por completo una gran pila. Por ejemplo:
futureEitherOr
// res6: FutureEitherOption[Int] = OptionT(
// EitherT(Future(Success(Right(Some(42))))))
val intermediate = futureEitherOr.value
// intermediate: FutureEither[Option[Int]] = EitherT(Future(Success(Right(Some(42)))))
val stack = intermediate.value
// stack: Future[Either[String, Option[Int]]] = Future(Success(Right(Some(42))))
Await.result(stack, 1.second)
// res7: Either[String, Option[Int]] = Right(Some(42))