Commits

Anonymous committed ca31fc6 Merge

Merged in jaxconf (pull request #5)

New slides for reader monad, monad transformers, and traverse.

  • Participants
  • Parent commits e8045e3, e96bb10

Comments (0)

Files changed (2)

images/turtle.jpg

Added
New image
 	<script src="extensions/menu/deck.menu.js"></script>
 	<script src="extensions/goto/deck.goto.js"></script>
 	<script src="extensions/status/deck.status.js"></script>
+<script>
+  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+  ga('create', 'UA-41301772-1', 'bitbucket.org');
+  ga('send', 'pageview');
+
+</script>	
 
 	<!-- highlight.js -->
 	<link rel="stylesheet" href="solarized_light.css">
   	<div style="font-size: 50%">John Kodumal, Atlassian</div>
   	<div style="font-size: 50%">jkodumal@atlassian</div>
 	<div style="font-size: 50%"><br/></div>
+	<div style="font-size: 25%">Use left and right arrows to navigate.</div>
 	<div style="font-size: 25%">Japanese translation by Shingo Omura is <a href="index-ja.html">here<a>.</div>
   </h1>
 </section>
 		<li class="slide"><em>Functional design patterns</em></li>
 		<li class="slide">There's mostly* nothing magical about these typeclasses</li>
 		<li class="slide">In scala, they're provided by a library called scalaz (pronounced scala-zed)</li>
-		<li class="slide">These examples are based on <a href="https://github.com/scalaz/scalaz/tree/scalaz-seven">scalaz-seven</a></li>
+		<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, and monads</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>
 
 
 <section class="slide">
 	<img src="images/macaulay.jpg" style="float: right; width: 100%;">
-	<h3>(The Macaulay Culkin Operator)</h3>
+	<h3>(The Macaulay Culkin Function)</h3>
 </section>
 
 <section class="slide">
 </pre>
 	<h6 class="slide">Exercise: Define the applicative instance for <code>Option</code></h6>
 	</div>
+	<div class="slide">
+	<p>With <code>point</code>, we can express the above example as:</p>
+<pre class="scala">
+	(parse("3") |@| 4.point[Option]) (_ + _)
+</pre>
+	</div>
 </section>
 
 <!--
 </section>
 
 <section class="slide">
+	<h2>One more motivating example</h2>
+	<div class="slide">
+	<p>Recall that there is a functor instance for functions:</p>
+	<pre>
+def map[A, B](fa: R => A)(f: A => B) : R => B = (x => f(fa(x)))
+	</pre>
+	</div>
+	<div class="slide">
+		<p>What about a monad instance?</p>	
+		<pre>
+implicit def FunctionMonad[R] = new Monad[({type l[a] = R=>a})#l] {
+	def flatMap[A, B](fa: R => A)(f: A => R => B) : R => B = (x => f(fa(x))(x))
+	...
+}
+		</pre>
+	</div>
+	<div class="slide">
+		<p>This is commonly referred to as the <code>Reader</code> monad. Here's why:</p>
+		<pre>
+val f = for {
+	t1 <- ((_:Int) + 2)
+  t2 <- ((_:Int) - 1)
+} yield t1 * t2
+		</pre>
+	<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>
+
+<section class="slide">
 	<h2>Monad as Embedded Language</h2>
 	<div class="slide">
-		<p>I'll present one <a href="http://en.wikibooks.org/wiki/Haskell/Understanding_monads">stab</a> at providing an intuition for monads. Consider:</p>
+		<p>Here's a <a href="http://en.wikibooks.org/wiki/Haskell/Understanding_monads">stab</a> at providing an intuition for monads. Consider:</p>
 <pre class="scala">
 for {
 	x <- monadicX
 			</tr>
 			<tr class="slide">
 				<td><code>Reader</code></td>
-				<td>Global environment</td>
+				<td>Read-only environment</td>
 			</tr>
 			<tr class="slide">
 				<td><code>Validation</code></td>
 	</div>
 </section>
 
+<section class="slide">
+	<h2>Languages with Multiple Effects</h2>
+	<p>In the real world, we have to deal with multiple monads (effects):</p>
+	<ul>
+		<li class="slide">A data store takes a DB configuration (<code>Reader</code>), and the connection may fail (<code>Validation</code>)</li>
+		<li class="slide">A computation may be asynchronous (<code>Future</code>), and may produce multiple results (<code>List</code>)</li>
+		<li class="slide">A remote call may fail if the service is down (<code>Validation</code>), and we want to log responses (<code>Writer</code>)</li>
+	</ul>
+	<div class="slide">
+	<p>Let's see why working with stacked monads gets ugly. We'll add a read-only environment to our calculator:</p>
+<pre class="scala">
+def lookup(s: String)(env: Map[String, Int]) = env.get(s) orElse parse(s)
+</pre>
+	</div>
+	<div class="slide">
+		<p>Now we'll add two numbers, using <code>Reader</code> to avoid repeating the <code>env</code> argument:</p>		
+<pre class="scala">
+for {
+ xOpt <- lookup("3") _
+ yOpt <- lookup("y") _
+} yield (for {
+          x <- xOpt
+          y <- yOpt
+         } yield x + y)
+</pre>
+	<p style="font-size: 60%">(Yuck)</p>
+	</div>
+</section>
+
+<section class="slide">
+	<img src="images/turtle.jpg" style="float: right; width: 100%;">
+	<h3>...all the way down</h3>
+</section>
+
+<section class="slide">
+	<h2>They see me composin'... they hatin'</h2>
+	<p>Life would be easier of monads <em>composed</em>. Given monads <code>M[_]</code> and <code>N[_]</code>, is <code>M[N[_]]</code> a monad? </p>
+	<div class="slide">
+		<p>We can work this out for functors:</p>
+<pre class="scala">
+implicit val ComposedFunctor[M: Functor, N: Functor] = new Functor[...] {
+	def map[A, B](fa: M[N[A]])(f: A => B) : M[N[B]] = fa.map(_.map(f(_)))
+}
+</pre>
+	</div>
+	<div class="slide">
+		<p>It's ironic (like rain on your wedding day), but in general, monads don't compose. Try it:
+<pre class="scala">
+implicit val ComposedMonad[M: Monad, N: Monad] = new Monad[...] {
+	def >>=[A, B](fa: M[N[A]])(f: A => M[N[B]]) : M[N[B]] = // ???
+}
+</pre>
+	</div>
+	<div class="slide">
+		<p>Our solution will involve introducing a new typeclass for <em>monad transformers</em>:</p>
+<pre class="scala">
+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 utility functions:</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>
+		<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: F[A] => (A => G[B]) => G[F[B]]</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>
+
+<section class="slide">
+	<h2>Monad composition for free</h2>
+	<div class="slide">
+		<p>Assuming we also have a <code>Traverse</code> requirement on monads <code>M</code> and <code>N</code>, we can get a composed monad for "free": </p>
+<pre class="scala">
+implicit val ComposedMonad[M: Monad, N: Monad: Traverse] = new Monad[...] {
+	def >>=[A, B](fa: M[N[A]])(f: A => M[N[B]]) : M[N[B]] = // ???
+}	
+</pre>
+		<h6 class="slide">Exercise: Implement <code> >>= </code> for <code>ComposedMonad</code>.</h6>
+	</div>
+	<div class="slide">
+		<p>This can be used to supply monad transformer implementations. Sometimes, though, this "free" transformer doesn't have the semantics we want.		
+	</div>
+
+</section>
+
 </body>
 </html>