Reputation: 4412
I have some problems when I want to use implicit methods to convert a function to something else.
I'm implementing a small DSL in Scala 2.8 for testing purposes. It should support various checks (assertions if you like) on instances. The whole DSL is a bit complex, but the following simplified example shows my problem:
object PimpMyFunction {
class A(val b: Int)
def b(a: A) = a.b
class ZeroCheck(f: A => Int) {
def isZeroIn(a: A) = f(a) == 0
}
implicit def fToCheck(f: A => Int): ZeroCheck = new ZeroCheck(f)
def main(args: Array[String]) {
val a0 = new A(0)
val a1 = new A(1)
println(fToCheck(b).isZeroIn(a0))
println(fToCheck(b).isZeroIn(a1))
println(b.isZeroIn(a0))
}
}
First two println lines (when I explicitly call the conversion method) compile and work fine, but the last one (when I want to rely on implicits) produces the error:
Compile error: missing arguments for method b in object PimpMyFunction; follow this method with '_' if you want to treat it as a partially applied function
If I want to implicitly convert "normal" instances (which are not functions) the same way it also works, so I guess the problem is not related to scoping/importing.
If I follow the instructions of the error message and use println((b _).isZeroIn(a0))
it also works, but the DSL is targeted at non technical people, so I would like to keep the syntax as clean and simple as possible.
I think I have another workaround (b should be a class extending an Assertions trait which already contain the check methods + A => Int) that would support the cleaner syntax, but it would be more verbose and less flexible, so I would prefer the implicit way.
Any ideas how to avoid the (b _)
syntax and still use implicits?
Upvotes: 3
Views: 730
Reputation: 297225
The problem happens because b
is not a function, but a method. Please look up related questions on that topic. If you define b
like below, though, you shouldn't have any problems:
def b = (_: A).b
This defines the type of b
to be a function.
Upvotes: 4
Reputation: 3034
Scala requires you to write (b _) to ensure that you really want the method b to be boxed to a function value. If you don't want to write the underscore, directly define b to be a function value instead of a method:
val b = (a: A) => a.b
Upvotes: 6