title: scala Either.RightProjection confusion (for comprehension de-sugaring)
body: <p>I can use an <code>=</code> in a scala for-comprehension (as specified in section <a href="http://www.scala-lang.org/docu/files/ScalaReference.pdf" rel="noreferrer"><strong>6.19</strong> of the SLS</a>) as follows:</p>
  
  <h2>Option</h2>
  
  <p>Suppose I have some function <code>String =&gt; Option[Int]</code>:</p>
  
  <pre><code>scala&gt; def intOpt(s: String) = try { Some(s.toInt) } catch { case _ =&gt; None }
  intOpt: (s: String)Option[Int]
  </code></pre>
  
  <p>Then I can use it thus</p>
  
  <pre><code>scala&gt; for {
     |     str &lt;- Option("1")
     |     i &lt;- intOpt(str)
     |     val j = i + 10    //Note use of = in generator
     |   }
     |   yield j
  res18: Option[Int] = Some(11)
  </code></pre>
  
  <p>It was my understanding that this was essentially equivalent to:</p>
  
  <pre><code>scala&gt; Option("1") flatMap { str =&gt; intOpt(str) } map { i =&gt; i + 10 } map { j =&gt; j }
  res19: Option[Int] = Some(11)
  </code></pre>
  
  <p>That is, the embedded generator was a way of injecting a <code>map</code> into a sequence of <code>flatMap</code> calls. So far so good.</p>
  
  <h2>Either.RightProjection</h2>
  
  <p><strong>What I actually want to do</strong>: <em>use a similar for-comprehension as the previous example using the <code>Either</code> monad</em>.</p>
  
  <p>However, if we use it in a similar chain, but this time using the <code>Either.RightProjection</code> monad/functor, it doesn't work:</p>
  
  <pre><code>scala&gt; def intEither(s: String): Either[Throwable, Int] = 
    |      try { Right(s.toInt) } catch { case x =&gt; Left(x) }
  intEither: (s: String)Either[Throwable,Int]
  </code></pre>
  
  <p>Then use:</p>
  
  <pre><code>scala&gt; for {
   | str &lt;- Option("1").toRight(new Throwable()).right
   | i &lt;- intEither(str).right //note the "right" projection is used
   | val j = i + 10
   | }
   | yield j
  &lt;console&gt;:17: error: value map is not a member of Product with Serializable with Either[java.lang.Throwable,(Int, Int)]
                i &lt;- intEither(str).right
                  ^
  </code></pre>
  
  <p>The issue has something to do with the function that a right-projection expects as an argument to its <code>flatMap</code> method (i.e. it expects an <code>R =&gt; Either[L, R]</code>). But modifying to not call <code>right</code> on the second generator, it still won't compile.</p>
  
  <pre><code>scala&gt;  for {
   |        str &lt;- Option("1").toRight(new Throwable()).right
   |        i &lt;- intEither(str) // no "right" projection
   |          val j = i + 10
   |      }
   |      yield j
  &lt;console&gt;:17: error: value map is not a member of Either[Throwable,Int]
                i &lt;- intEither(str)
                              ^
  </code></pre>
  
  <h2>Mega-Confusion</h2>
  
  <p>But now I get doubly confused. The following works just fine:</p>
  
  <pre><code>scala&gt; for {
   |       x &lt;- Right[Throwable, String]("1").right
   |       y &lt;- Right[Throwable, String](x).right //note the "right" here
   |     } yield y.toInt
  res39: Either[Throwable,Int] = Right(1)
  </code></pre>
  
  <p>But this does not:</p>
  
  <pre><code>scala&gt; Right[Throwable, String]("1").right flatMap { x =&gt; Right[Throwable, String](x).right } map { y =&gt; y.toInt }
  &lt;console&gt;:14: error: type mismatch;
   found   : Either.RightProjection[Throwable,String]
   required: Either[?,?]
                Right[Throwable, String]("1").right flatMap { x =&gt; Right[Throwable, String](x).right } map { y =&gt; y.toInt }
                                                                                               ^
  </code></pre>
  
  <p>I thought these were equivalent</p>
  
  <ul>
  <li>What is going on?</li>
  <li>How can I embed an <code>=</code> generator in a for comprehension across an <code>Either</code>?</li>
  </ul>