我很难理解curried函数(有一个参数)与普通方法的区别。我尝试用前者实现后者,但是无法实现。
我的Market
特征定义如下:
package market {
trait Market {
def getBuyRate(currency: String): Double
def getSellRate(currency: String): Double
}
}
我有另一个FakeMarket
特征延伸Market
,我希望使用currying来实现getBuyRate
和getSellRate
,如下所示:
package market {
trait FakeMarket extends Market with Iterable[Double] {
def getRate(factor: Double)(currency: String): Double = {
factor * this.iterator.next()
}
def getBuyRate = getRate(1) _
def getSellRate = getRate(1.02) _
}
}
最后,我有RandomFakeMarket
对象扩展FakeMarket
:
package market {
object RandomFakeMarket extends FakeMarket {
def iterator = new Iterator[Double] {
def hasNext = true
def next = 100.0
}
}
}
如此定义类型会出错:
<console>:10: error: object creation impossible, since:
it has 2 unimplemented members.
/** As seen from object RandomFakeMarket, the missing signatures are as follows.
* For convenience, these are usable as stub implementations.
*/
def getBuyRate(currency: String): Double = ???
def getSellRate(currency: String): Double = ???
object RandomFakeMarket extends FakeMarket {
^
这对我来说似乎很奇怪,因为FakeMarket
实现了getBuyRate
类getSellRate
和String => Double
类型的方法。
如果在Market
我做过:
getBuyRate: String => Double
为什么这与我最初定义getBuyRate
的方式不同?当只有一个论点时,为什么这会有所不同?现在似乎父特质Market
必须担心getBuyRate
如何实现(正常函数与curried函数)。
答案 0 :(得分:4)
与currying没那么相关。 def method(p1: String, p2: String): String
与scala中的def method: (String, String) => String
不等效。方法和函数之间的区别在于方法支持继承,因此他们需要知道方法的输入和输出,由于含糊不清,这种方法并不那么明显:
def get: String => Double
可以是String -> Double
(统一成员)和() -> String -> Double
(解释为函数)。但是在scala中它是Function1[String, Double]
或() Function1[String, Double]
,它们的意思是没有输入。不幸的是,def get(): String => Double
在这里没有区别(见下面的例子)。
换句话说,方法可能没有scala中的输入参数(因为副作用可能不是纯函数),因此它无法从{{(String)Double
推断String => Double
1}}所以你的整个函数成为一个输出参数。例如,您可以在某个子类中执行override def method: (String, String) => String
- 这将覆盖没有参数且返回类型为(String, String) => String
的方法,但不会使用输入(String, String)
覆盖该方法并返回类型String
另一个问题是方法的类型与函数不同,并且可能只通过eta-expansion进行单向转换,因此scala与UAP有点不兼容:
scala> def aaa(b: String): String = "aaa"
aaa: (b: String)String
scala> aaa _
res4: String => String = <function1>
scala> def aaa: String => String = (a: String) => "aa"
aaa: String => String
scala> def aaa()(b: String): String = "aaa"
aaa: ()(b: String)String
scala> def aaa(): String => String = (a: String) => "aa"
aaa: ()String => String
关于方法与功能的更多信息:Difference between method and function in Scala