Note that there are some explanatory texts on larger screens.

plurals
  1. POScala view application puzzler
    primarykey
    data
    text
    <p>Say we have the following two traits:</p> <pre><code>trait Foo[A] { def howMany(xs: List[A]) = xs.size } trait Bar </code></pre> <p>And an implicit conversion from the second to the first:</p> <pre><code>implicit def bar2foo[A](bar: Bar) = new Foo[A] {} </code></pre> <p>We create a <code>Bar</code> and a list of integers:</p> <pre><code>val bar = new Bar {} val stuff = List(1, 2, 3) </code></pre> <p>Now I'd expect the following to work:</p> <pre><code>bar howMany stuff </code></pre> <p>But it doesn't:</p> <pre><code>scala&gt; bar howMany stuff &lt;console&gt;:13: error: type mismatch; found : List[Int] required: List[A] bar howMany stuff ^ </code></pre> <p>So we go to <a href="http://www.scala-lang.org/docu/files/ScalaReference.pdf" rel="nofollow noreferrer">the spec</a>, which has this to say (emphasis in bold is mine):</p> <blockquote> <p>Views are applied in three situations.</p> <ol> <li><p>[Isn't relevant here.]</p></li> <li><p>In a selection <em>e.m</em> with <em>e</em> of type <em>T</em>, <strong>if the selector <em>m</em> does not denote a member of <em>T</em></strong>. In this case, a view <em>v</em> is searched which is applicable to <em>e</em> and whose result contains a member named <em>m</em>. The search proceeds as in the case of implicit parameters, where the implicit scope is the one of <em>T</em>. If such a view is found, the selection <em>e.m</em> is converted to <em>v(e).m</em>.</p></li> <li><p>In a selection <em>e.m(args)</em> with <em>e</em> of type <em>T</em>, <strong>if the selector <em>m</em> denotes some member(s) of <em>T</em>, but none of these members is applicable to the arguments <em>args</em></strong>. In this case a view <em>v</em> is searched which is applicable to <em>e</em> and whose result contains a method <em>m</em> which is applicable to <em>args</em>. The search proceeds as in the case of implicit parameters, where the implicit scope is the one of <em>T</em>. If such a view is found, the selection <em>e.m</em> is converted to <em>v(e).m(args)</em>.</p></li> </ol> </blockquote> <p>So we try the following, thinking it must be too absurd to work:</p> <pre><code>trait Foo[A] { def howMany(xs: List[A]) = xs.size } trait Bar { def howMany = throw new Exception("I don't do anything!") } implicit def bar2foo[A](bar: Bar) = new Foo[A] {} val bar = new Bar {} val stuff = List(1, 2, 3) </code></pre> <p>But it does (on both 2.9.2 and 2.10.0-RC2, at least):</p> <pre><code>scala&gt; bar howMany stuff res0: Int = 3 </code></pre> <p>This leads to some really strange behavior, as for example in <a href="https://gist.github.com/4131492" rel="nofollow noreferrer">this workaround</a> for <a href="https://stackoverflow.com/q/13507202/334519">this problem</a>.</p> <p>I have three (closely related) questions:</p> <ol> <li>Is there a straightforward way (i.e., one that doesn't involve adding fake methods with the appropriate name) to have the view applied correctly in the original case above?</li> <li>Can someone provide a reading of the spec that accounts for this behavior?</li> <li>Assuming this is the intended behavior, does it make any sense at all?</li> </ol> <p>I'd also appreciate any links to previous discussions of this issue—I haven't been having much luck with Google.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload