如何使用适当的apply方法将对象隐式转换为函数?

Pet*_*itz 2 scala

正如问题所说我正在尝试以下(不编译):

  object O {
    def apply(i: Int): Boolean = i % 2 == 0
  }
  val f: Int => Boolean = O
Run Code Online (Sandbox Code Playgroud)

所以我尝试了这个:

  implicit def apply2Fct[A,B](applier: { def apply(a: A): B }) = {
    new Function[A,B] { def apply(a: A): B = applier(a) }
  }
Run Code Online (Sandbox Code Playgroud)

但是编译器抱怨"结构细化中的参数类型可能不会引用在该细化之外定义的抽象类型".

编辑:

由于Jean-Philippe Pellet的回答,我不得不提到我不能分别O延长.Function[A,B]Function[Int,Boolean]

Mil*_*bin 6

你不能直接这样做是因为Gilles给出的#967票.有问题的构造是在结构类型中的方法定义的裸参数位置中出现外部定义的类型参数A.

但是,我们可以通过消除有问题的发生来有利于内部类型参数与类型约束相结合,从而迫使它在应用该方法的任何点处等于原始参数类型A.

要做到这一点,你必须修改你试图从结构上捕获的方法的签名的一般形式(nb.pseudocode follow),

def method(x : <<your arg type>>) : <<your result type>>
Run Code Online (Sandbox Code Playgroud)

def method[T](x : T)(implicit ev : T =:= <<your arg type>>) : <<your result type>>
Run Code Online (Sandbox Code Playgroud)

对于您的特定情况,我们需要类似以下内容,

object O {
  def apply[T](i : T)(implicit ev : T =:= Int) : Boolean = i % 2 == 0
}

implicit def apply2Fct[A,B](applier: { def apply[T](a: T)(implicit ev : T =:= A): B }) = {
  new Function[A,B] { def apply(a: A): B = applier(a) }
}
Run Code Online (Sandbox Code Playgroud)

示例REPL会话,

scala> implicit def apply2Fct[A,B](applier: { def apply[T](a: T)(implicit ev : T =:= A): B }) = {
     | new Function[A,B] { def apply(a: A): B = applier(a) }
     | }
apply2Fct: [A, B](applier: AnyRef{def apply[T](a: T)(implicit ev: =:=[T,A]): B})java.lang.Object with (A) => B

scala> object O {
     | def apply[T](i : T)(implicit ev : T =:= Int) : Boolean = i % 2 == 0
     | }
defined module O

scala> O(23)
res0: Boolean = false

scala> O(24)
res1: Boolean = true

scala> val f: Int => Boolean = O
f: (Int) => Boolean = <function1>                                                                                                                                                                                                              

scala> f(23)                                                                                                                                                                                                                                   
res2: Boolean = false                                                                                                                                                                                                                          

scala> f(24)                                                                                                                                                                                                                                   
res3: Boolean = true  
Run Code Online (Sandbox Code Playgroud)