gpt4 book ai didi

scala - Scala 函数是否可以编写为获取任何函数并以相反的参数返回该函数?

转载 作者:行者123 更新时间:2023-12-02 09:13:02 26 4
gpt4 key购买 nike

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

PS:这是 Clojure 中的函数:

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

最佳答案

主要困难在于,您必须找出具有相反参数的函数的类型,并且如果没有宏,则不可能以通用方式做到这一点。

但是由于 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库,它是在内部使用宏实现的。这是一个使用 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 - Scala 函数是否可以编写为获取任何函数并以相反的参数返回该函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49990810/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com