我有几个与咖喱功能有关的问题.我在这里逐一问他们
1)http://twitter.github.com/scala_school/basics.html给出了一个curried函数的例子 - 我认为它是一个函数定义,但实际上并非如此.REPL根本不承认这是一个有效的声明.
multiplyThenFilter { m: Int => m * 2 } { n: Int => n < 5}
Run Code Online (Sandbox Code Playgroud)
2)为什么我们不能从部分参数化方法定义函数?即,以下定义有什么问题?
scala> def multiply(m: Int, n: Int): Int = m * n
multiply: (m: Int, n: Int)Int
scala> val timesTwo = multiply(2,_)
<console>:11: error: missing parameter type for expanded function ((x$1) => multiply(2, x$1))
val timesTwo = multiply(2,_)
^
Run Code Online (Sandbox Code Playgroud)
3)为什么我们不能使部分参数化函数curry?即,以下定义有什么问题?
scala> (multiply(_,_)).curried
res13: Int => (Int => Int) = <function1> // THIS IS OK
scala> (multiply(20,_)).curried
<console>:12: error: missing parameter type for expanded function ((x$1) => multiply(20, x$1))
(multiply(20,_)).curried
^
Run Code Online (Sandbox Code Playgroud)
Tra*_*own 12
斯卡拉学校例子是混乱的,它绝对不是一个定义.在GitHub上有一个问题,所以也许这是一个bug.您可以想象一个合理的定义可能如下所示:
def multiplyThenFilter(f: Int => Int)(p: Int => Boolean): Int => Option[Int] = {
i =>
val j = f(i)
if (p(j)) Some(j) else None
}
Run Code Online (Sandbox Code Playgroud)
(或者,相当于f andThen (Some(_) filter p).)
然后,该示例将是一个函数,它将其输入加倍并返回结果,Some如果它小于5,则返回结果None.但是,在对该问题做出回应之前,没有人确切知道作者的意图.
你timesTwo不工作的原因只是Scala编译器不支持那种类型推断 - 请参阅这个问题和我的答案,以获得一些相关的细节.您需要使用以下其中一项:
def multiply(m: Int, n: Int): Int = m * n
val timesTwo = multiply(2, _: Int)
def multiply(m: Int)(n: Int): Int = m * n
val timesTwo = multiply(2) _
Run Code Online (Sandbox Code Playgroud)
即,如果您想在此处进行类型推断,则需要使用多个参数列表.否则你必须帮助编译器输出类型.
对于您的第三个问题,假设我们在第二个问题中有以下内容以避免此问题:
val timesTwo = multiply(2, _: Int)
Run Code Online (Sandbox Code Playgroud)
这是一个Function1,只是没有curried方法 - 你需要一个Function2(或Function3等).
谈论用单个参数来讨论函数是没有意义的.Currying采用具有多个参数的函数,并为您提供一个函数,该函数采用返回另一个函数的单个参数(它本身可能需要一个参数并返回另一个函数,等等).
| 归档时间: |
|
| 查看次数: |
926 次 |
| 最近记录: |