Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Yes, there is. Let me give a simpler example. I hope this will also work with your more complicated use case.</p> <p>say we have</p> <pre><code>trait Foo[A] class Bar { def methWithImplicits[A,B](f: A =&gt; B)(implicit foo: Foo[A]) = null } implicit def fooInt: Foo[Int] = null </code></pre> <p>Now this has exactly the problem you describe, since</p> <pre><code>(new Bar).methWithImplicits(x =&gt; x) </code></pre> <p>gives "missing parameter type".</p> <p>So what we would like to do, is to move the implicit parameter "behind" the explicitly supplied function, so that Scala sees the implicit <em>first</em>. Well, one way we can do this is to add an extra layer of indirection:</p> <pre><code>class Bar { def methWithImplicits2[A](implicit foo: Foo[A]) = new { def apply[B](f: A =&gt; B) = null } } (new Bar).methWithImplicits2.apply(x =&gt; x) </code></pre> <p>This works, though the syntax is not so pretty. One way you might consider prettying the syntax is to look at your current design and see if you can sneak the implicit into any of the "earlier" stages. For example, since the <code>mapValuesStrict</code> method is only meaningful once the implicit has been supplied, you might make the implicit a property of the object instead of passed to the method.</p> <p>But if that is not convenient in your design, you could use an extra implicit conversion to sneak it back. This is what we would like to do:</p> <pre><code>implicit def addFoo[A](bar: Bar)(implicit foo: Foo[A]) = new { def methWithImplicits3[B](f: A =&gt; B) = null } </code></pre> <p>But unfortunately there is what I suspect is a bug in Scala that causes it to search for an implicit value that is too polymorphic, causing it to complain:</p> <pre><code>could not find implicit value for parameter foo: test.Foo[A] </code></pre> <p>This only happens when using implicit conversions, which is why I think it is a bug. So, we can take it <em>back even further:</em> (and, requiring <code>-Xexperimental</code> for dependent method types):</p> <pre><code>trait FooWrapper { type AA val foo: Foo[AA] } implicit def wrapFoo[A](implicit theFoo: Foo[A]) = new FooWrapper { type AA = A val foo = theFoo } implicit def addFoo(bar: Bar)(implicit foo: FooWrapper) = new { def methWithImplicits3[B](f: foo.AA =&gt; B) = null } </code></pre> <p>And now</p> <pre><code>(new Bar).methWithImplicits3(x =&gt; x) </code></pre> <p>works perfectly ;)</p> <hr> <p><strong>Update</strong></p> <p>In your particular case, I think your best bet is to work the implicit into <code>enhanceGenTraversable</code>, though, alas, the same hack is required to work around the possible bug:</p> <pre><code>// Notice `ev` is now a field of the class class EnhancedGenTraversableLike[A, Repr &lt;: GenTraversable[A], T, U] (self: GenTraversableLike[A, Repr], ev: A &lt;:&lt; (T, U)) { def mapValuesStrict[R, That](f: U =&gt; R)(implicit bf: CanBuildFrom[Repr, (T, R), That]) = { val b = bf(self.asInstanceOf[Repr]) b.sizeHint(self.size) for ((k: T, v: U) &lt;- self) b += k -&gt; f(v) b.result } } // The Hack trait WrappedPairBound[A] { type TT type UU val bound: A &lt;:&lt; (TT, UU) } implicit def wrapPairBound[A,T,U](implicit ev: A &lt;:&lt; (T,U)) = new WrappedPairBound[A] { type TT = T type UU = U val bound = ev } // Take the implicit here implicit def enhanceGenTraversableLike[A, Repr &lt;: GenTraversable[A]] (self: GenTraversableLike[A, Repr])(implicit ev: WrappedPairBound[A]) = new EnhancedGenTraversableLike[A, Repr, ev.TT, ev.UU](self, ev.bound) </code></pre>
    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.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      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