1

map型に対して暗黙の引数で定義されたいくつかのメソッドを試してみると問題が発生しOptionます。

私がカスタムを定義classtrait、前述のメソッドが上記で動作しているとしましょう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引数関数に明示的に渡すと考えられていますが、実際の関数で使用する場合、コンパイラーは暗黙の定義を要求します。

私には2つの可能な解決策がありますが、どちらも満足のいくものではありません。

  1. のように暗黙の引数をoptionally渡す

    optionally(implicit my => stringy)

  2. のように、特定の関数への引数をとして定義することは避けてimplicitください

    def stringy(arg: MyClass)

各ソリューションは、読みやすさと使いやすさの両方を達成するという目標に反しています。

行くための3番目の方法はありますか?

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 に答える