我正在尝试学习 Figaro,由于它是在 Scala 中实现的,所以我遇到了一些 Scala 特定的问题。例如,在下面的代码中,Importance.probability
有两个参数,第一个是分布,第二个是谓词。但是,当我尝试运行此代码时,出现以下错误:
Missing argument for greaterThan50
这是有道理的,因为它实际上需要一个参数。
由于 Scala 是一种函数式语言,我猜想有一些智能的标准方法可以将函数作为我错过的参数发送?我曾尝试使用 _
使其部分应用,但这不起作用。
import com.cra.figaro.library.atomic.continuous.Uniform
import com.cra.figaro.algorithm.sampling.Importance
def greaterThan50(d: Double) = d > 50
val temperatur = Uniform(10,70)
Importance.probability(temperatur, greaterThan50)
最佳答案
请注意,在 Scala 中,您可以传递 function value ,例如 greaterThan50
,其中需要一个函数。
在这种情况下,在probability
方法中,定义为
def probability[T](target: Element[T], predicate: T => Boolean): Double
第二个参数是一个函数,但为什么当你传递 greaterThan50
实际上是一个函数值时编译器不接受?
因为Importance
中还有一个重载方法,定义如下:
def probability[T](target: Element[T], value: T): Double
所以当我们调用
Importance.probability(temperatur, greaterThan50)
编译器实际上选择了 seconds 重载方法。这就是为什么它会尽力在某些值上应用 greaterThan50
方法,以便在返回中获得一些结果,该结果可用作类型为 T
的第二个参数.
在这种情况下,为了消除歧义,您需要 partially apply the function :
Importance.probability(temperatur, greaterThan50 _)
这消除了这种情况的歧义,因为现在 greaterThan50 _
的类型是 Double => Boolean
,它与第一个重载函数完全匹配。
实验证明
为了确保这种方法在非重载方法中有效,您可以简单地尝试在您的上下文中定义以下函数(例如在 object
中):
def probability[T](target: Element[T], predicate: T => Boolean): Double = 10
并调用它
probability(temperatur, greaterThan50) // Note that this function is defined by you
你会看到没有编译错误,因为编译器需要一个函数,而你给它一个函数值。
其他选项
当然你可以传递一个function literal 概率
:
Importance.probability[Double](temperatur, (x: Double) => x > 50)
或者您可以像这样定义 greaterThan50
:
def greaterThan50 = (d: Double) => d > 50
这将是 (Double) => Boolean
类型,这又是一个完全匹配。
免责声明
使用 figaro
版本 2.4.0.0
和 Scala 版本 2.11.2
。
关于scala - 在 Scala/Figaro 中将函数作为参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26470033/