【问题标题】:unwanted implicit argument resolution in higher order function map高阶函数映射中不需要的隐式参数解析
【发布时间】:2013-02-04 14:19:55
【问题描述】:

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

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

  1. 将隐式参数传递给optionally,如

    optionally(implicit my =&gt; stringy)

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

    def stringy(arg: MyClass)

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

还有第三条路吗?

【问题讨论】:

    标签: scala implicit higher-order-functions


    【解决方案1】:

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

    def s: Option[String] = optionally(stringy(_))
    def l: Option[Int] = optionally(lengthy(_))
    def i: Option[Int] = optionally(inty(_))
    

    【讨论】:

    • 很好,这是否意味着无法部分应用带有隐式参数的方法? def f[A](implicit a: A) = a 但没有:val ff = f _?
    • 至少不是简单地省略参数列表,看起来
    猜你喜欢
    • 1970-01-01
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    • 2013-05-08
    相关资源
    最近更新 更多