scala – 是否有一种通用的方法来反转curried函数的参数顺序?
发布时间:2020-12-16 18:04:16 所属栏目:安全 来源:网络整理
导读:我想知道你是否可以编写一个泛型函数,它接受一个curried函数,然后反转参数,如下所示: def foo(a: String)(b: Boolean)(c: Int): Stringval bar = invert(foo _)foo("baz")(false)(12) must be equalTo(bar(12)(false)("baz")) 只要您为要解决的特定情况添加
我想知道你是否可以编写一个泛型函数,它接受一个curried函数,然后反转参数,如下所示:
def foo(a: String)(b: Boolean)(c: Int): String val bar = invert(foo _) foo("baz")(false)(12) must be equalTo(bar(12)(false)("baz")) 只要您为要解决的特定情况添加隐式逆变器,以下操作就可以正常工作.但我对更一般的情况更感兴趣 – 也就是说,处理任何数量的讨论论点的情况. trait Inverter[V,W] { def invert(v: V): W } implicit def function2Inverter[X,Y,Z] = new Inverter[(X,Y) => Z,(Y,X) => Z] { def invert(v: (X,Y) => Z) = { def inverted(y: Y,x: X) = v(x,y) inverted _ } } implicit def curried2Inverter[X,Z] = new Inverter[X => Y => Z,Y => X => Z] { def invert(v: (X) => (Y) => Z) = { def inverted(y: Y)(x: X) = v(x)(y) inverted _ } } def invert[V,W](v: V)(implicit inverter: Inverter[V,W]): W = inverter.invert(v) 哦,我希望有一个适用于Scala 2.9的解决方案. 解决方法
TL; DR:使用
this gist.以下说明如下:
首先,定义一个类型类(和个案)以部分应用具有最后一个参数的函数: trait PopLast[A,Last,Rem] { def pop(f: A,v: Last): Rem } trait LowPrioPopLast { implicit def popEnd[A,B] = new PopLast[A => B,A,B] { def pop(f: A => B,v: A) = f(v) } } object PopLast extends LowPrioPopLast { implicit def popOne[A,B,C,IRem]( implicit iPop: PopLast[B => C,IRem]) = new PopLast[A => B => C,A => IRem] { def pop(f: A => B => C,v: Last) = { a: A => iPop.pop(f(a),v) } } } 然后,创建逆变器类型类:递归地执行最后一个参数的部分应用并反转结果. trait Inverter[A] { type Out def invert(f: A): Out } trait LowPrioInverter { implicit def invertEnd[A,B] = new Inverter[A => B] { type Out = A => B def invert(f: A => B) = f } } object Inverter extends LowPrioInverter { implicit def invertStep[A,Rem](implicit pop: PopLast[A,Rem],inv: Inverter[Rem]) = new Inverter[A] { type Out = Last => inv.Out def invert(f: A) = { a: Last => inv.invert(pop.pop(f,a)) } } } 最后,封装成一个函数: def invert[A](f: A)(implicit inv: Inverter[A]) = inv.invert(f) 然后我们去: def foo(a: String)(b: Boolean)(c: Int): String = "bar" val bar = invert(foo _) // bar: Int => Boolean => String => String bar(1)(true)("foo") (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- angularjs – 为什么我必须调用$scope?$digest()在这里?
- 在vim和python virtualenv中带有taglist的ctags
- [MySQL]快速解决"is marked as crashed and should be
- bash脚本根据文件名中的日期查找旧文件
- scala – 当在对象上定义而不在类上定义时,方法是尾递归的
- bootstrap daterangepicker双日历时间段选择控件详解
- Bootstrap 表单
- Angular 1.6提示$http.get(...).success is not a function
- scala – 模式匹配不起作用
- twitter-bootstrap-3 – Bootstrap折叠 – 全部展开