Commits

Anonymous committed 217688e

More on monad transformers

Comments (0)

Files changed (1)

   t2 <- ((_:Int) - 1)
 } yield t1 * t2
 		</pre>
-	<p>Think of <code>Reader</code> as a computation awaiting a <em>read-only environment</em> (the argument) to be supplied.</p>
+	<p>Think of <code>Reader</code> as a computation with a <em>read-only environment</em> (the argument) that can be supplied to produce a result.</p>
 	</div>	
 </section>
 
 </pre>
 	</div>
 	<div class="slide">
-		<p>Time for a new typeclass:</p>
+		<p>We'll introduce a new typeclass:</p>
 <pre class="scala">
-trait MonadTrans {
-	def liftM
+trait MonadTrans[F[_[_], _]] {
+  def liftM[G[_] : Monad, A](a: G[A]): F[G, A]
 }
 </pre>
 	</div>
+
+</section>
+
+
+<section class="slide">
+	<h2>More on transformers</h2>
+	<div class="slide">
+		<p>We're going to box a monadic computation:</p>
+<pre class="scala">
+case class OptionT[F[+_], +A](run: F[Option[A]]) { ... }
+</pre>
+	</div>
+	<div class="slide">
+		<p>The boxed value exposes the underlying monad's interface:</p>
+		<pre code="scala">
+OptionT(List(Some(3), None, Some(4))).getOrElse(0) // List(3, 0, 4)
+		</pre>
+	</div>
+	<div class="slide">
+		<p>Most importantly, the boxed value is itself a monad!</p>
+<pre class="scala">
+(for {
+	x <- OptionT(List(Some(3), None))
+	y <- List(1,2).liftM[OptionT]
+} yield x + y).run // List(Some(4), None, Some(5), None)
+</pre>
+	</div>
 </section>
 
 </body>