我在尝试map
使用Option
类型的隐式参数定义的某些方法时遇到问题。
假设我定义了一个自定义class
和一个trait
,其中上述方法在class
上运行
class MyClass
trait Processor {
def stringy(implicit arg: MyClass) = arg.toString
def lengthy(implicit arg: MyClass) = arg.toString.length
def inty(implicit arg: MyClass) = arg.toString.map(_.toInt).sum
}
然后我用一些测试创建一个实现
object TestProcessing extends Processor {
//Here everything works fine, the argument is passed explicitly
def test() {
val my = new MyClass
val res = List(stringy(my), lengthy(my), inty(my))
println(res.mkString("\n"))
}
//Still everything ok, the argument is passed implicitly
def testImplicit() {
implicit val my = new MyClass
val res = List(stringy, lengthy, inty)
println(res.mkString("\n"))
}
object Mapper {
//class wrapped in an Option
val optional = Some(new MyClass)
//trying to factor out common code
def optionally[T](processFunction: MyClass => T): Option[T] = optional map processFunction
//now the specific processing methods that should work on the optional value
def s: Option[String] = optionally(stringy)
def l: Option[Int] = optionally(lengthy)
def i: Option[Int] = optionally(inty)
/*
* Here the compiler complains that
*
*<console>:40: error: could not find implicit value for parameter arg: MyClass
* def s: Option[String] = optionally(stringy)
* ^
*<console>:41: error: could not find implicit value for parameter arg: MyClass
* def l: Option[Int] = optionally(lengthy)
* ^
*<console>:42: error: could not find implicit value for parameter arg: MyClass
* def i: Option[Int] = optionally(inty)
* ^
*/
}
}
虽然optionally
被设想为显式地将可选值显式传递给它的参数函数,但是当我在实际函数上使用它时,编译器需要一个隐式定义。
我有两种可能的解决方案,两者都不令人满意:
将隐式参数传递给optionally
,如
optionally(implicit my => stringy)
避免将特定函数的参数定义为implicit
,如
def stringy(arg: MyClass)
每个解决方案都无法实现可读性和可用性的目标。
还有第三种方法吗?
答案 0 :(得分:1)
如果我理解正确,问题是编译器似乎没有意识到你想在这里部分地将方法应用/提升到一个函数(而是“认为”你想要省略隐含参数),所以明确地这样做似乎有效:
def s: Option[String] = optionally(stringy(_))
def l: Option[Int] = optionally(lengthy(_))
def i: Option[Int] = optionally(inty(_))