Scala中与函数相关的问题

Scala中与函数相关的问题,scala,Scala,我有几个问题与curry函数有关。在这里,我一个接一个地问他们 1) 给出了一个curried函数的例子——我以为这是一个函数定义,但实际上不是。REPL根本不认为这是一条有效的语句 multiplyThenFilter { m: Int => m * 2 } { n: Int => n < 5} multiplyThenFilter{m:Int=>m*2}{n:Int=>ndef乘法(m:Int,n:Int):Int=m*n 乘法:(m:Int,n:Int)Int

我有几个问题与curry函数有关。在这里,我一个接一个地问他们

1) 给出了一个curried函数的例子——我以为这是一个函数定义,但实际上不是。REPL根本不认为这是一条有效的语句

multiplyThenFilter { m: Int =>   m * 2 } { n: Int =>   n < 5}
multiplyThenFilter{m:Int=>m*2}{n:Int=>n<5}
2) 为什么我们不能从部分参数化方法定义函数?i、 例如,以下定义有什么问题

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,_)
                                 ^
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
                           ^
scala>def乘法(m:Int,n:Int):Int=m*n
乘法:(m:Int,n:Int)Int
scala>val times2=multiply(2,u)
:11:错误:扩展函数缺少参数类型((x$1)=>乘法(2,x$1))
val times2=乘法(2,u2;)
^
3) 为什么我们不能使一个部分参数化的函数变成curried?i、 例如,以下定义有什么问题

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,_)
                                 ^
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
                           ^
scala>(乘法(,)).curried
res13:Int=>(Int=>Int)=//这没问题
scala>(乘法(20,))).curried
:12:错误:扩展函数缺少参数类型((x$1)=>乘法(20,x$1))
(乘以(20,))curried
^
问题1 Scala学校的例子令人困惑,它绝对不是一个定义。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
}
(或者,相当于,
f,然后(一些(u)过滤器p)

然后,该示例将是一个函数,该函数将其输入加倍,如果小于5,则返回
Some
,否则返回
None
。但在对这个问题做出回应之前,没有人确切知道作者的意图


问题2 您的
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) _
也就是说,如果你想在这里进行类型推断,你需要使用多个参数列表。否则,您必须帮助编译器处理类型


问题3 对于第三个问题,假设我们有以下内容来避免第二个问题中的问题:

val timesTwo = multiply(2, _: Int)
这是一个
Function1
,它只是没有一个
curried
方法。为此,您需要
Function2
(或
Function3
,等等)


谈论用一个参数来实现函数是没有意义的。Currying接受一个具有多个参数的函数,并为您提供一个接受一个参数的函数,该函数返回另一个函数(它本身可能接受一个参数并返回另一个函数,等等)。

1)它无效,因为必须先声明它。例如,像这样:
def multiplyThenFilter(a:Int=>Int)(b:Int=>Boolean)={List(1,2,3,4).map(a).filter(b)}
1)multiplyThenFilter现在不见了。你不是唯一被它弄糊涂的人:-)在你对问题2的回答中,“val times2=multiply(2,Int:Int)”和“val times2=multiply(2)中定义的两个函数“times2”是同一类型的吗?是的,它们都是
Int=>Int
(或者等价地
Function1[Int,Int]
)。