传递一个带有类型参数的函数作为参数

时间:2013-06-03 18:55:21

标签: scala type-parameter

我想创建一个函数g,它将函数f作为参数,其中f具有类型参数。我无法获得编译的g签名。一次尝试是这样的:

scala> def mock1[A](): A = null.asInstanceOf[A] // STUB
mock1: [A]()A

scala> def mock2[A](): A = null.asInstanceOf[A] // STUB
mock2: [A]()A

scala> def g0(f: [A]() => A): Int = f[Int]()
<console>:1: error: identifier expected but '[' found.
       def g0(f: [A]() => A): Int = f[Int]()
                 ^

如果我将包含类型参数的函数包装在特征中,我可以使它工作,如下所示:

scala> trait FWrapper { def f[A](): A }
defined trait FWrapper

scala> class mock1wrapper extends FWrapper { def f[A]() = mock1[A]() }
defined class mock1wrapper

scala> class mock2wrapper extends FWrapper { def f[A]() = mock2[A]() }
defined class mock2wrapper

scala> def g(wrapper: FWrapper): Int = wrapper.f[Int]()
g: (wrapper: FWrapper)Int

scala> g(new mock1wrapper)
res8: Int = 0

有没有办法可以在不引入包装类的情况下完成此任务?

2 个答案:

答案 0 :(得分:6)

Scala(目前)不支持多态函数值。您有两种选择:

  1. 坚持你的包装特性(可能最容易理解)
  2. 使用来自Shapeless的多态函数值(花哨,但可能有点复杂)

答案 1 :(得分:0)

这个怎么样:

  def mock[A](): A = null.asInstanceOf[A]

  def g[A](f:() => A): A = f()

  g(mock[Int])