title: How do pattern match assignments in for comprehensions translate into monadic operations?
body: <p>I am familiar with the concept that Scala's <code>for</code> comprehensions are just syntactic sugar for monadic operations (<code>map</code>, <code>withFilter</code>, <code>foreach</code>, and <code>flatMap</code>) and the desugaring is described in <a href="https://stackoverflow.com/a/1059501/1243041">this popular answer</a>.</p>
  <p>By that logic, I was surprised to find that, when using pattern matching as part of the assignment portion of a <code>for</code> comprehension, no <code>MatchError</code> is thrown when the pattern doesn't match an element. Instead, the non-matched element is filtered out:</p>
  <pre class="lang-scala prettyprint-override"><code>case class Account(id: String, role: String)
  val accounts = Set(Account(&quot;a&quot;, &quot;ADMIN&quot;), Account(&quot;b&quot;, &quot;USER&quot;), Account(&quot;c&quot;, &quot;ADMIN&quot;), Account(&quot;d&quot;, &quot;USER&quot;), Account(&quot;e&quot;, &quot;USER&quot;))
  
  val adminIds = for (Account(id, &quot;ADMIN&quot;) &lt;- accounts) yield id
  // Set(&quot;a&quot;, &quot;c&quot;) (no MatchError on Account(&quot;b&quot;, &quot;USER&quot;)!
  </code></pre>
  <p>I would have expected that comprehension to translate to something like this:</p>
  <pre class="lang-scala prettyprint-override"><code>val adminIds = accounts.map { case Account(id, &quot;ADMIN&quot;) =&gt; id }
  
  // or maybe
  val adminIds = accounts.map { account =&gt;
    val Account(id, &quot;ADMIN&quot;) = account
    id
  }
  
  </code></pre>
  <p>But of course those would throw a <code>MatchError</code>. Instead it seems more similar to this:</p>
  <pre class="lang-scala prettyprint-override"><code>val adminIds = accounts.collect { case Account(id, &quot;ADMIN&quot;) =&gt; id }
  </code></pre>
  <p>However, I've never seen any mention of a <code>for</code> comprehension desugaring into a <code>collect</code> call.</p>
  <p>So how is this done under the hood?</p>