Commits

Anonymous committed 4e52780

Progress on Traverse

Comments (0)

Files changed (1)

 		<li class="slide">These examples are based on <a href="https://github.com/scalaz/scalaz/">scalaz 7.0.0</a></li>
 		<li class="slide">This is how the hierarchy is defined in Haskell--- it isn't perfect</li>
 	</ul>
-	<p class="slide">We'll cover functors, applicative functors, monads (and monad transformers), foldable, and traversable</p>
+	<p class="slide">We'll cover functors, applicative functors, monad, monad transformers, and traversable</p>
 	<p class="slide" style="font-size: 60%">*one exception: <code>for</code> comprehensions and monads</p>
 </section>
 
 		</pre>
 	</div>
 	<div class="slide">
-		<p>Most importantly, the boxed value is itself a monad!</p>
+		<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>
+		<p>We can stack transformers arbitrarily deep!</p>
+	</div>
+</section>
+
+<section class="slide">
+	<h2>De-turtling our previous example</h2>
+	<div class="slide">
+		<p>scalaz defines transformers for most common monads:</p> 
+		<ul>
+			<li><code>OptionT</code>
+			<li><code>ListT</code>
+			<li><code>EitherT</code>
+			<li><code>ReaderT</code>, aka <code>Kleisli</code>
+		</ul>		
+	</div>
+	<div class="slide">
+		<p>Let's clean up our previous example with <code>ReaderT</code>. Recall we had:
+<pre class="scala">
+for {
+ xOpt <- lookup("3") _
+ yOpt <- lookup("y") _
+} yield (for {
+          x <- xOpt
+          y <- yOpt
+         } yield x + y)
+</pre>			
+	</div>
+	<div class="slide">
+		<p>With <code>ReaderT</code>:
+<pre class="scala">
+for {
+	x <- Kleisli(lookup("3") _)
+	y <- Kleisli(lookup("y") _)
+} yield x + y
+</pre>
+	<p style="font-size:60%">(Much nicer!)</p>
+	</div>
+</section>
+
+<section class="slide">
+	<h2>Another take on composing monads</h2>
+	<div class="slide">
+		<p>An alternative formulation of <code>Monad</code> provides some insight into the composition problem. Instead of <code>bind</code>, it's sufficient to implement <code>join</code>:<p>
+		<pre class="scala">
+trait Monad[F[_]] extends Applicative {
+	def join[A](fa: F[F[A]]): F[A]
+}
+		</pre>
+	</div>
+	<h6 class="slide">Exercise: Define <code> >>= </code> using <code>join</code> and <code>map</code></h6>
+	<div class="slide">
+		<p>Using <code>join</code>, let's try to make a monad for <code>M[N[_]]</code>. Substituting <code>M[N[_]]</code> for <code>F</code>, we get:</p>
+<pre class="scala">
+def join[A](fa: M[N[M[N[A]]]]]): M[N[A]]
+</pre>
+		<p style="font-size: 60%">(Whew!)</p>			
+	</div>
+	<div class="slide">
+		<p>The <code>join</code> methods defined on <code>M</code> and <code>N</code> don't help, because they're "blocked" by the other monad. But what if we could "commute" the monads?
+<pre class="scala">
+def commute[A](a: M[N[A]]): N[M[A]]
+</pre>
+	</div>
+	<div class="slide">
+		<p>This works! It's possible to define monad composition given the <code>commute</code> function.</p>
+	</div>
+</section>
+
+<section class="slide">
+	<h2>Introducing Traverse</h2>
+	<div class="slide">
+	<p>The <code>Traverse</code> typeclass provides exactly this: the ability to commute two functors</p>
+	<pre class="scala">
+trait Traverse[F[_]] extends Functor {
+	def sequence[G[_]: Applicative, A](fga: F[G[A]]): G[F[A]]
+}
+	</pre>	
+			<p style="font-size: 60%">(scalaz uses an alternative formulation based on a function <code>traverse</code>)</p>	
+	</div>
+	<div class="slide">
+		<p><code>Traverse</code> is tremendously handy in its own right. For example, let's turn a list of asynchronous computations into an asynchronous computation of a list:</p>
+<pre class="scala">
+List(future { doCalc1() }, future { doCalc2() }).sequence // Future[List[Int]]
+</pre>
 	</div>
 </section>