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

标签 scala figaro-lang

我正在尝试学习 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/

相关文章:

scala - 如何在Scala中打印出列表的类型?

scala - scala 中的特征推断

scala - Slick 2.1.0 中可选的嵌套映射实体

machine-learning - Figaro概率规划参数学习

scala - 自动将案例类转换为无形的可扩展记录?

json - Scala 发送 GET 请求,无法解析 json 响应