【问题标题】:Can a Scala function be written such that it gets any function and returns it with its arguments reversed?可以编写一个 Scala 函数,使其获取任何函数并返回它的参数反转吗?
【发布时间】:2018-04-23 22:27:22
【问题描述】:

我知道这在 lisp 中是微不足道的,但 Scala 有一个强大的类型系统,这让我怀疑这样的功能是否可行。 如果不可能,那么宏呢? Scala 宏可以做到这一点吗?

PS:这是 Clojure 中的函数:

 (fn [f](fn f* [& args] (apply f (reverse args))))

【问题讨论】:

  • 参数是否都属于同一类型?我什么时候需要它?如果参数的类型不同,我会用参数调用反转函数,这些参数与我传递它们的顺序不匹配?如果我不立即执行函数,为什么我要传递函数而不仅仅是要反转的参数?

标签: scala higher-order-functions


【解决方案1】:

主要的困难是你必须找出带有反向参数的函数的类型,如果没有宏,这是不可能的。

但由于 Scala 仅支持最多 22 个参数的函数,因此您可以为所有可能的参数的函数编写或生成 23 个实现。这是一个有 3 个参数的函数的示例:

def reverse[A, B, C, R](f: (A, B, C) => R): (C, B, A) => R = 
  (c, b, a) => f(a, b, c)

使用宏虽然可以以通用方式进行。最简单的解决方案可能是使用shapeless 库,它是在内部使用宏实现的。这是一个无形的示例实现:

import shapeless._
import shapeless.ops.function._
import shapeless.ops.hlist._

def reverseArgs[Func, Args <: HList, Res, RevArgs <: HList](f: Func)(implicit
  // Convert the function to a function from a single HList argument.
  fnToProduct: FnToProduct.Aux[Func, Args => Res], 
  // Compute the type of the reversed arguments HList.
  r1: Reverse.Aux[Args, RevArgs],
  // Get the function to reverse the reversed arguments back.
  reverse: Reverse.Aux[RevArgs, Args],
  // Convert the function of a single HList argument to a normal function
  fnFromProduct: FnFromProduct[RevArgs => Res]
): fnFromProduct.Out = {
  fnFromProduct((args: RevArgs) => fnToProduct(f)(reverse(args)))
}

这是它的工作原理:

scala> val f = reverseArgs((i: Int, d: Double, s: String) => (i + d).toString + s)
f: (String, Double, Int) => String = shapeless.ops.FnFromProductInstances$$anon$4$$Lambda$1191/2014583896@4d7933e7

scala> f("a", 1.5, 2)
res1: String = 3.5a

【讨论】:

  • 您是否还可以使用纯 Scala(无宏)添加具有 arity 3 的函数的情况?而且我不明白你为什么定义r1。你没有使用它。 (我不知道任何 Shapeless 所以也许这就是原因)。
  • @HappyFace 我用纯 Scala 添加了一个案例。至于r1,是的,我没用过。正如评论所说,它只是为了计算反向参数列表的类型。真正使用的函数是 reverse 的逆(称为reverse)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-14
相关资源
最近更新 更多