简体   繁体   中英

Scala error: missing parameter type for expanded function

I am trying to write a query library for Scala. Here is the code so far:

class Query[TElement](source: Traversable[TElement]) {
    def join[TOther](other: Traversable[TOther]) = new {
        def on[TKey](keySelector1: TElement => TKey) = new {
            def equals(keySelector2: TOther => TKey) = new {
                def into[TResult](resultSelector: (TElement, TOther) => TResult): Query[TResult] = {
                    val map = source.map(e => (keySelector1(e), e)).toMap
                    val results = other
                        .map(e => (keySelector2(e), e))
                        .filter(p => map.contains(p._1))
                        .map(p => (map(p._1), p._2))
                        .map(p => resultSelector(p._1, p._2))
                    new Query[TResult](results)
                }
            }
        }
    }
}

object Query {
    def from[TElement](source: Traversable[TElement]): Query[TElement] = {
        new Query[TElement](source)
    }
}

...

val results = Query.from(users)
    .join(accounts).on(_.userId).equals(_.ownerUserId).into((_, _))

I get the following error when I go to compile:

error: missing parameter type for expanded function ((x$2) => x$2.ownerUserId)

I am a little confused why I would get this error on the non-generic function equals . Its generic parameters come from the outer scope, I'd think. I know to fix it I have to explicitly say what the parameter type is by writing (a: Account) => a.ownerUserId . However, I am trying to make it a pretty fluent library, and this is making it messy.

The problem is quite simple. There is an ambiguity with the existing method equals that is inherited from Any . Simple example:

scala> class X[A, B] { def equals(f: A => B) = f }
defined class X

scala> val x = new X[Int, String]
x: X[Int,String] = X@52d455b8

scala> x.equals((x: Int) => x.toString)
res0: Int => String = <function1>

scala> x.equals((x: String) => x.toString) // uh-oh
res1: Boolean = false

As one can see in the last example, when the wrong function type is passed, the compiler has to choose def equals(Any): Boolean . When you don't specify any type, the compiler has to infer one, which it can't do in the example.

Simply rename your method to something else and the problem is gone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM