加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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,只返回未触及的函数.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读