如何知道分配了哪个功能?

How know which function was assigned?

提问人:gilcu2 提问时间:7/25/2018 最后编辑:Andrey Tyukingilcu2 更新时间:7/26/2018 访问量:50

问:

如果我有这样的东西:

def fn1(a:Integer)="1"
def fn2(a:Integer)="2"
val f=fn2 _
if( f== fn1 _) "1" else if(f==fn2 _) "2" else "other"

始终返回“other”。如何在代码中知道哪个函数被分配给了 f?

Scala Lambda 相等

评论

0赞 Andrey Tyukin 7/25/2018
在这种特殊情况下,唯一确定它是 WAS 还是 。否则,我不明白你在问什么。函数的外延相等性(通常)是不可判定的。f(0)fn1fn2
0赞 gilcu2 7/25/2018
我想知道哪个功能分配给了 f。真实案例不是这样微不足道的,所以无法解决评估功能
1赞 Andrey Tyukin 7/25/2018
正如我上面提到的,图灵完备语言中一般函数的扩展相等性是不可判定的。定义 时,您正在通过 eta 扩展方法构造一个新函数。没有其他对象会等于这个函数,只有会返回,每隔一个比较总是会产生。ffn2f == ftruefalse
0赞 Tim 7/26/2018
@AndreyTyukin我认为他问的是比较函数引用,而不是函数本身。
0赞 Andrey Tyukin 7/26/2018
@Tim 正如你在我的回答中看到的,这是我能想到的唯一普遍适用的解决方案。但这有点无聊,而且毫无意义,因为,很明显,你总是可以比较引用,它与函数无关。 还会给你()和()...val a = new AnyRef; val b = new AnyRefa == atruea == bfalse

答:

1赞 gilcu2 7/25/2018 #1

这也有效:

def fn1(a:Integer)="1"
def fn2(a:Integer)="2"

val f1=fn1 _
val f2=fn2 _
val f=f2
f match {
case `f1` => "1"
case `f2` => "2"
case _ => "other"
}
1赞 Andrey Tyukin 7/25/2018 #2

由于函数的外延相等性(粗略地说:被认为是“等于”当且仅当所有有效输入)通常是不可判定的,因此您基本上只有两个选择:fgf(x) == g(x)x

  1. 对于每个函数,附加一些抽象描述,您可以在其上定义可判定的等价关系。例如,您可以构造这些函数的符号表示,您可以为其定义内涵相等或一些稍强的等价关系,以近似于自下而上的外延相等(可能难以任意实现,限制了它工作的函数集)。

  2. 使用 JVM 引用相等:

    val fn1: (Int => String) = a => "1"
    val fn2: (Int => String) = a => "2"
    val f = fn2
    println(if(f == fn1) "1" else if(f == fn2) "2" else "other")
    

    这将输出 .请注意,这种相等是非常“脆弱”的,例如,"2"

    val fn3: (Int => String) = a => "2"
    

    将不等于 。fn2

评论

0赞 Andrey Tyukin 7/26/2018
现在这变得有趣了。在任何地方都犯了什么错误?
0赞 Andrey Tyukin 7/26/2018
至少,我看不出它与这里所说的任何内容相矛盾。约尔格·米塔格(Jörg W Mittag)甚至勾勒出为什么外延函数相等一定是不可判定的证明......
0赞 Alexey Romanov 7/26/2018
我怀疑,如果提问者知道什么是“外延相等”,他一开始就不需要这个问题,所以扩展它会很有用。
0赞 Andrey Tyukin 7/26/2018
@AlexeyRomanov 真的。但我只是想加入一些 OP 可以谷歌搜索的关键字(如果他愿意的话)。我不想花太多时间在定义和解释上,因为我怀疑OP无论如何都希望在参考文献上平等,因为其他一切都会很快变得相当复杂。无论如何,在引言中添加了一个非常简短的解释,只是为了强调函数还有其他有意义的“相等”概念。
0赞 Andrey Tyukin 7/27/2018
我喜欢这个答案的开头:图灵完备编程语言中的扩展相等性通常是无法确定的。