gpt4 book ai didi

scala - Scala函数转换

转载 作者:行者123 更新时间:2023-12-04 13:24:14 27 4
gpt4 key购买 nike

说我有一个函数接受一个参数

def fun(x: Int) = x

基于此,我想生成一个具有相同调用约定的新函数,但是在委派给原始函数之前,将对其参数进行一些转换。为此,我可以
def wrap_fun(f: (Int) => Int) = (x: Int) => f(x * 2)
wrap_fun(fun)(2) // 4

除了对所有仅具有部分参数以共同应用转换的函数之外的其他函数,人们将如何做同样的事情?
def fun1(x: Int, y: Int) = x
def fun2(x: Int, foo: Map[Int,Str], bar: Seq[Seq[Int]]) = x

wrap_fun(fun1)(2, 4) // 4
wrap_fun(fun2)(2, Map(), Seq()) // 4

进行上述调用的 wrap_fun定义将如何工作?

最佳答案

这可以通过使用shapeless's工具直接抽象出函数Arity来完成,

import shapeless._
import HList._
import Functions._

def wrap_fun[F, T <: HList, R](f : F)
(implicit
hl : FnHListerAux[F, (Int :: T) => R],
unhl : FnUnHListerAux[(Int :: T) => R, F]) =
((x : Int :: T) => f.hlisted(x.head*2 :: x.tail)).unhlisted

val f1 = wrap_fun(fun _)
val f2 = wrap_fun(fun1 _)
val f3 = wrap_fun(fun2 _)

REPL session 示例,
scala> f1(2)
res0: Int = 4

scala> f2(2, 4)
res1: Int = 4

scala> f3(2, Map(), Seq())
res2: Int = 4

请注意,您不能立即应用包装的函数(如在问题中),而不是通过分配的val(如上所述),因为包装的函数的显式参数列表将与 wrap_fun的隐式参数列表混淆。我们最接近问题表格的方式是显式命名 apply方法,如下所示:
scala> wrap_fun(fun _).apply(2)
res3: Int = 4

scala> wrap_fun(fun1 _).apply(2, 4)
res4: Int = 4

scala> wrap_fun(fun2 _).apply(2, Map(), Seq())
res5: Int = 4

在这里,对 apply的明确提及从语法上标记了第一个应用程序( wrap_fun及其隐式参数列表)与第二个应用程序(转换后的函数及其显式参数列表)。

关于scala - Scala函数转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10216278/

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