0

我对此有点挣扎:我需要一个函数,该函数采用 fun(Any*) 类型的任何函数:布尔值作为参数,评估函数并返回真或假,具体取决于函数评估的成功与否。

本质上,我需要的是一个函数类型,它允许任何数字和任何类型的参数,但该函数必须返回布尔值。

这将允许我编写如下函数:

def checkLenght(str : String, length : Int) : Boolean ={
if (str.lenght == length)}

或者

def ceckAB(a : Int, b : Int) : Boolean = {
if(a < b && a >= 23 && b < 42) }

这样,例如

eval(checkLenght(abc, 3)) //returns true

eval(ceckAB(4,1)) // returns false 

我想,一个函数类型:

  type CheckFunction = (Any*) => Boolean

可能会成功,但我很难编写通用的 eval 函数。

有什么建议吗?

谢谢

解决方案:

该函数需要 1) 返回类型为 Boolean 的另一个函数:"(func : => Boolean)" 2) 返回类型为 Boolean ":Boolean" 3) 返回传递的函数参数的值:" = func"

总的功能是:

   def eval(func : => Boolean) : Boolean = func

再次让我惊讶的是,Scala 中的事情是多么简单。

正如评论所指出的,这是一个相当不寻常的功能,没有明显的意义。简单说一下根本原因。

动机:

有很多关于潜在动机的问题,所以这里简短总结一下为什么需要这样的功能。

本质上,有两个原因。

第一个是将故障处理从函数本身移到处理函数中。这保留了检查功能的纯度,甚至允许重用通用检查。

其次,这都是关于“可插拔故障处理”的。这意味着, eval 函数仅告知是否发生了故障(或未发生)。如果发生故障,则通过接口调用处理程序。可以根据需要使用配置文件交换处理程序的实现。

为什么?

交换配置文件意味着,我像往常一样编码我的检查和功能,但是通过切换配置文件,我切换处理程序,这意味着我可以在句号、控制台打印输出、电子邮件警报、SNMP 通知、推送消息之间进行选择... . 为此,我需要将检查函数与其评估和处理分离。这就是这种看起来相当奇怪的 eval 函数的动机。

为了完整起见,我已经实现了所有这些东西,但是我是否面临只处理琐碎检查的限制,即 check(Boolean*) 这很简洁,但我通常更愿意编写一个函数来进行更复杂的检查。


解决了

该函数是通过返回传递函数的值来定义的:

def eval(func : => Boolean) : Boolean = {func}
4

2 回答 2

2

我不能说我真的理解你想做你想做的事的动机,但我想这不是重点。也许该eval函数会在调用提供的函数之前检查某些内容,而不是在某些特定条件下调用其他函数(如快速失败)。也许您在调用该函数后进行一些后期检查并根据其他内容更改结果。无论哪种方式,我想您都可以使用如下所示的代码完成与您想要的类似的事情:

def main(args: Array[String]) {
  val str = "hello world"
  println(eval(checkLength(str, 3)))
  println(eval(intsEqual(1,1)))
}

def eval(func: => Boolean):Boolean = {
  //Do whetever you want before invoking func, maybe
  //not even invoke it if some other condition is present
  val fres = func

  //Maybe change something here before returning based on post conditions
  fres
}

def checkLength(s:String, len:Int) = s.length() == len
def intsEqual(a:Int, b:Int) = a == b

如果您真的希望该eval函数能够支持任何接受任何类型的 args 并返回 aBoolean的函数,那么使用这样的别名函数,然后利用别名函数内部的闭包将任何参数传递给任何您要调用的实际功能。证明这一点的更好方法如下:

def checkMyString(str:String, len:Int) = {
  eval(str.length == len)
}

str.length == len除非eval决定调用它,直到您将其扩展为它的真实形式,否则可能很难看到不会调用该检查:

def checkMyString(str:String, len:Int) = {
  def check = {
   str.length == len 
  }
  eval(check)
}

在这里,嵌套函数check可以访问str并且len由于闭包,这将允许您绕过eval必须能够使用返回 a 的任何参数调用函数的要求Boolean

这只是解决您的问题的一种方法,它甚至可能不适合您的需求,但我只是想把它扔在那里。

于 2013-06-06T12:19:39.740 回答
1

如果您的输入函数只有 2 个参数,就像您的两个示例一样,您可以编写一个半通用函数 take 接受具有任何类型的两个参数的所有函数:

def eval[A,B](func: (A,B) => Boolean, arg1: A, arg2: B) = {
    func(arg1, arg2)
}

def checkLength(str: String, length: Int) : Boolean = {
    str.length == length
}

eval(checkLength, "ham", 4)
res0: Boolean = false

但是,如果您想支持具有更多参数的函数,则必须eval为三个参数、四个参数等编写一个函数

也许有更好的方法可以处理所有情况?

于 2013-06-06T07:10:04.893 回答