作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
郑重声明,我发现 Scala 中的函数不会自动柯里化(Currying),这很烦人。我正在尝试编写一个接受任何函数并返回柯里化(Currying)版本的工厂:
def curry(fn:(_ => _)) = (fn _).curried
基本上,我在这里定义的是一个函数 curry
,它以 _ => _
类型的函数 fn
作为参数并返回函数 fn
的柯里化(Currying)版本。显然这没有用,因为 Java。
这是我得到的错误:
error: _ must follow method; cannot follow fn.type
def curry(fn:(_ => _)) = (fn _).curried
有哪位专家能帮我弄清楚为什么这不起作用吗?我不想听起来很尖刻,我习惯于将所有类型都视为函数的函数式语言。请帮助这个 Scala 新手。
(我用 haskell 标记了这个问题,因为我试图让 Scala 函数表现得像 Haskell 函数:'(
更新
澄清一下,我需要一个 curryN
函数,这样一个函数可以柯里化(Currying)任何其他函数,而不管其元数如何。
旁注,有些人指出增加 fn 的参数数量可以解决问题。不:
def curry2(fn:((_, _) => _)) = (fn _).curried
error: _ must follow method; cannot follow fn.type
def curry2(fn:((_, _) => _)) = (fn _).curried
最佳答案
Scala 不允许您对函数的元数进行抽象。因此,您需要使用类型类样式的方法(它允许您在完成所有手动工作后对几乎所有内容进行抽象)。
所以,特别是,你做类似的事情
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, B, Z]: Function2Currier[A, B, Z] =
new Function2Currier[A, B, 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 中可能已经有类似的东西,但在这种情况下,您可以自己动手,尽管需要一些乏味(和/或代码生成器)。
(注意:如果你想“柯里化(Currying)”A => Z
,你可以写一个Function1Currier
,它只返回原封不动的函数。)
关于scala - 编写一个函数来柯里化(Currying)任何函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38022322/
我是一名优秀的程序员,十分优秀!