在Scala中从Generic创建Closure

Hak*_*kar 5 swt scala

我正在尝试做一些我不确定Scala的类型系统是否允许我这样做的事情.

我基本上想要从泛型定义创建一个闭包并返回该闭包,同时在同一类型内部执行一个函数.

例如:

val f = async[(str:String, i:Int, b:BigInt) => Unit]({ (String, Int, BigInt) =>
  // Code here...
})

// 'f' would have a type of (String, Int, BigInt) => Unit and would wrap the passed anonymous function
Run Code Online (Sandbox Code Playgroud)

定义的理论范例:

  def async[T](
    shell: Shell,
    success: T,
    failure: (Throwable) => Unit): T = {
        new T {
          val display = shell.getDisplay()
          display.asyncExec(new Runnable() {
            def run(): Unit = {
              try {
                success(_)
              } catch {
                case e:Throwable =>
                  failure(e)
              }
            }
          })
        }
  }
Run Code Online (Sandbox Code Playgroud)

这将允许我有一个简单的系统为SWT创建异步回调,同时保持SWT不受我的业务逻辑的影响.

Tra*_*own 9

您可以使用Shapeless库更加通用.我们定义wrap如下:

import shapeless._, Functions._

def wrap[F, A <: HList, R](f: F)(implicit
  h: FnHListerAux[F, A => R],
  u: FnUnHListerAux[A => R, F]
): F = { (args: A) => 
  println("Before f")
  val result = f.hlisted(args)
  println("After f")
  result
}.unhlisted
Run Code Online (Sandbox Code Playgroud)

然后可以像这样使用它:

scala> val sum: (Int, Int) => Int = _ + _
sum: (Int, Int) => Int = <function2>

scala> val wrappedSum = wrap(sum)
wrappedSum: (Int, Int) => Int = <function2>

scala> wrappedSum(100, 1)
Before f
After f
res0: Int = 101
Run Code Online (Sandbox Code Playgroud)

这适用于任何arity的功能.

所以在Scala中是可能的,尽管做一些没有Shapeless的东西几乎肯定会是一个巨大的麻烦.