2012-03-22 69 views
0

我有一个函数foo接受一个布尔函数斯卡拉布尔函数抽象

def foo(f:(_)=>Boolean) = //do something with f 

我可以调用foo如下

foo((x:Int) => x == 0) 

现在,我要修改富接受返回布尔任何功能。例如。修改后的foo应该适用于以下情况。

foo((x:Int, y:Int) => x == y) 
foo((x:Int, y:Int, z:Int) => x == y && y == z) 
foo((x:Double, y:Double, z:Double, p:Double) => x < y && y < z && z < p) 
//and so on... 

我第一次尝试如下

def foo2(f:(_*)=>Boolean) = //do something with f 

修改FOO但是,这是行不通的。

+2

“用f做什么”真的有用吗?你能显示代码吗? – 2012-03-22 12:27:59

+0

@ n.m。让我给一些背景。这是一个编译器插件。编译器插件将从函数的主体中提取一个逻辑公式。函数的参数是公式中的自由变量。 – dips 2012-03-22 13:02:12

+0

您似乎会调用一个具有未知数量参数的函数。你能显示代码吗? – 2012-03-22 13:18:29

回答

1

什么@Nicolas说。

使用Function.tupled可以使呼叫站点代码略微更好。

scala> def foo[A](f: A => Boolean) = 0 
foo: [A](f: A => Boolean)Int 

scala> import Function.tupled 
import Function.tupled 

scala> foo(tupled((x: Int, y: Int) => x == y)) 
res0: Int = 0 

scala> foo(tupled((x: Int, y: Int, z: Int) => x < y && y < z)) 
res1: Int = 0 
+0

谢谢。这看起来很干净。这现在对我来说很有用。但有一点需要注意。这对于超过5个参数的函数不起作用。 Function.scala中有一个注释_“这些函数已被弃用,但它被搁置,以等待匿名函数的优先类型推断。”_ – dips 2012-03-22 13:59:45

+0

@dips,5个参数的东西不是基本的限制。你可以使用'Function.tupled'方法编写自己的tupling方法。 – missingfaktor 2012-03-22 14:33:17

+0

@dips,更新的写法是'f.tupled'(而不是旧的'Function.tupled(f)')。正如笔记所说,老式的方式与类型提供者更友好。 – missingfaktor 2012-03-22 14:34:38

4

是否适合您的需要def foo[A](pred: A => Boolean)

例如:

def foo[A](pred: A => Boolean): A => Boolean = {x:A => 
    if (pred(x)) { 
    println("Yeah!") 
    true 
    } else { 
    false 
    } 
} 

然后:

foo {xy:(Int, Int) => xy._1 == xy._2} 

foo {xyz:(Int, Int, Int) => xyz._1 == xyz._2 && xyz._2 == xyz._3} 
+0

谢谢。这将工作。但._1有点不方便。让我们等待几天的其他答案。 – dips 2012-03-22 12:58:08

+0

不幸的是,在你的例子中,给定的函数分别扩展了'Function2'和'Function3',这些特性和'Function'没有任何公共的超类(除了'Any'),所以你将无法为你的功能找到一个有效的签名。这就是为什么你必须玩'Tuple's和他们的'_x'符号。 – Nicolas 2012-03-22 13:20:17

1

如果您需要处理超过5个参数,你可以重载foo您需要但是很多争论。斯卡拉(目前)只能处理高达Function22的功能,所以你可以用22行代码覆盖所有的可能性,并且呼叫站点使用率很好。

def foo[T](f: (T) => Boolean) = true 
def foo[T](f: (T, T) => Boolean) = true 
def foo[T](f: (T, T, T) => Boolean) = true 
def foo[T](f: (T, T, T, T) => Boolean) = true 
def foo[T](f: (T, T, T, T, T) => Boolean) = true 
// snip 
def foo[T](f: (T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) => Boolean) = true 

优雅,没有。作品,是的。