Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to describe and fix this Scala type mismatch error?
    text
    copied!<p>Below is a specific instance of a kind of situation that I sometimes encounter with parameterized types. Basically, there are type parameters that I know are compatible, but I don't know how to prove that to some parts of the code.</p> <p>I'm writing a request router that maps urls to handler functions. Below is some simplified code. I create a <code>List[Route]</code> where a <code>Route</code> is basically a <code>UrlMatcher, Function</code> pair.</p> <pre><code>class Route[A](matcher: UrlMatcher[A], handler: HandlerFunction[A]) abstract class UrlMatcher[A] { def match(url: String): Option[A] // None if no match </code></pre> <p>The type parameter <code>A</code> is for the "arguments" that the matcher might extract from the URL. They would be passed to the handler function. For example, a <code>UrlMatcher[Int]</code> that sees a URL path like "/users/123" could pass 123 to a <code>getUser(id: Int)</code> function. The router might look like:</p> <pre><code>val routes = ArrayBuffer[Route[_]] def callHandler(url: String) { for (r &lt;- routes) { val args = r.matcher.matchUrl(url) if (args.isDefined) r.handler(args.get) // &lt;--- error here } </code></pre> <p>The problem is that I get type mismatch errors because I don't know how to tell it the two types are the same. </p> <pre><code>type mismatch; found: args.type (with underlying type Option[Any]) required: _$1 </code></pre> <p>I know I can redesign it so that <code>Route</code> has a method like <code>matchAndCall</code>, but I'd like to keep this logical flow if possible. </p> <p><strong>Update/Edit</strong></p> <p>I don't fully understand existential types, but I tried this...</p> <pre><code>val routes = ArrayBuffer[T forSome { type T }]() </code></pre> <p>And it removed the mismatch error above. However, I have another one where I was inserting into the <code>ArrayBuffer</code>.</p> <pre><code>def route[P](matcher: UrlMatcher[P], handler: Handler[P]): AbstractRoute = { val route = new Route(matcher, handler) otherRoutes.append(route) // error here route } </code></pre> <p>Now the error is...</p> <pre><code>type mismatch; found : Route[P] required: Route[T forSome { type T }] Note: P &lt;: T forSome { type T }, but class Route is invariant in type P. You may wish to define P as +P instead. (SLS 4.5) </code></pre> <p>Why is <code>P</code> incompatible with <code>T</code>, since their are no constraints on <code>T</code>?</p>
 

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