在Scala / Figaro中将函数作为参数传递

时间:2014-10-20 16:05:13

标签: scala figaro-lang

我试图学习Figaro,因为它是在Scala中实现的,我遇到了一些Scala特定的问题。例如,在下面的代码中,Importance.probability有两个参数,第一个是分布,第二个是谓词。但是当我尝试运行此代码时,我收到以下错误:

  

缺少参数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)

2 个答案:

答案 0 :(得分:5)

请注意,在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)

编译器实际上选择了秒重载方法。这就是为什么它会尽力在某个值上应用greaterThan50方法,以便获得一些可以作为T类型的第二个参数返回的结果。< / p>

在这种消除歧义的情况下,您需要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传递给probability

Importance.probability[Double](temperatur, (x: Double) => x > 50)

或者您可以像这样定义greaterThan50

def greaterThan50 = (d: Double) =>  d > 50

属于(Double) => Boolean类型,这又是完全匹配。

声明

已使用Scala版本figaro的{​​{1}}版本2.4.0.0

答案 1 :(得分:0)

这不起作用的原因是因为您调用了一个名为probability的方法而不是您认为正在调用的方法。

您正在调用具有此签名的伴随对象的probability方法:

def probability[T](target: Element[T], value: T, numSamples: Int = 10000): Double

你可能想要这样的东西:

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)
val alg = Importance(myNumSamples = 100, temperatur)
alg.start()
alg.probability(temperatur, greaterThan50 _)

考虑查看使用Importance。{/ p>的Hello World教程