1

我在尝试map使用隐式参数定义的某些方法时遇到问题Option

假设我使用上述方法定义了一个 customclass和 atraitclass

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被设想显式地将可选值显式传递给它的参数函数,但当我在实际函数上使用它时,编译器需要一个隐式定义。

我有两种可能的解决方案,但都不令人满意:

  1. 将隐式参数传递给optionallyas in

    optionally(implicit my => stringy)

  2. 避免将特定函数的参数定义为implicit,如

    def stringy(arg: MyClass)

每个解决方案都违背了实现可读性和可用性的目标。

有没有第三条路可以走?

4

1 回答 1

1

如果我理解正确,问题是编译器似乎没有认识到您想要将方法部分应用/提升到这里的函数(相反它“认为”您想要省略隐式参数),所以明确地这样做似乎工作:

def s: Option[String] = optionally(stringy(_))
def l: Option[Int] = optionally(lengthy(_))
def i: Option[Int] = optionally(inty(_))
于 2013-02-04T15:11:26.457 回答