scala – 编写一个函数来curry任何函数
发布时间:2020-12-16 10:05:33 所属栏目:安全 来源:网络整理
导读:为了记录,我发现在 Scala中不会自动计算函数非常烦人.我正在尝试编写一个接收任何函数并返回curried版本的工厂: def curry(fn:(_ = _)) = (fn _).curried 基本上我在这里定义的是一个函数curry,它将函数fn作为参数,类型为_ = _并返回函数fn的curried版本.显
为了记录,我发现在
Scala中不会自动计算函数非常烦人.我正在尝试编写一个接收任何函数并返回curried版本的工厂:
def curry(fn:(_ => _)) = (fn _).curried 基本上我在这里定义的是一个函数curry,它将函数fn作为参数,类型为_ => _并返回函数fn的curried版本.显然这不起作用,因为Java. 这是我得到的错误: error: _ must follow method; cannot follow fn.type def curry(fn:(_ => _)) = (fn _).curried 任何大师都可以帮我弄清楚为什么这不起作用?我并不是说听起来很讽刺,我习惯于将所有类型作为函数处理的函数式语言.请帮助这个Scala新手. (我用haskell标记了这个问题,因为我试图让Scala函数表现得像Haskell函数:'( UPDATE 只是为了澄清,我需要一个curryN函数,所以一个函数可以调整任何其他函数而不管它的arity. 旁注,有人指出增加fn参数的数量可以解决问题.不: def curry2(fn:((_,_) => _)) = (fn _).curried error: _ must follow method; cannot follow fn.type def curry2(fn:((_,_) => _)) = (fn _).curried 解决方法
Scala不允许您对函数的arity进行抽象.因此,您需要使用类型类方法(在完成所有手动工作之后,它允许您抽象几乎所有内容).
所以,特别是你做的事情 sealed trait FunctionCurrier[Unc,Cur] { def apply(fn: Unc): Cur } final class Function2Currier[A,B,Z] extends FunctionCurrier[(A,B) => Z,A => B => Z] { def apply(fn: (A,B) => Z): (A => B => Z) = fn.curried } // Repeat for Function3 through Function21 implicit def makeCurrierForFunction2[A,Z]: Function2Currier[A,Z] = new Function2Currier[A,Z] // Again,repeat for Function3 through Function21 def curryAll[Unc,Cur](fn: Unc)(implicit cf: FunctionCurrier[Unc,Cur]): Cur = cf(fn) 现在您可以像这样使用它: scala> def foo(a: Int,b: String) = a < b.length foo: (a: Int,b: String)Boolean scala> curryAll(foo _) res0: Int => (String => Boolean) = <function1> 在Shapeless中可能已经有类似的东西了,但在这种情况下你可以自己滚动,虽然有一些乏味(和/或代码生成器). (注意:如果你想“咖喱”A => Z,你可以编写一个Function1Currier,只返回未触及的函数.) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |