【问题标题】:How know which function was assigned?如何知道分配了哪个功能?
【发布时间】:2018-07-25 15:20:20
【问题描述】:

如果我有这样的事情:

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

总是返回“其他”。如何在代码中知道哪个函数分配给了 f?

【问题讨论】:

  • 在这种特殊情况下,f(0) 唯一地确定它是fn1 还是fn2。否则,我不明白你在问什么。函数的外延相等(通常)是不可判定的。
  • 我想知道哪个函数被分配给了 f。真实情况并非如此简单,因此无法解决评估函数
  • 正如我上面提到的,图灵完备语言中通用函数的外延相等性是不确定的。在定义f 时,您通过对方法fn2 进行eta 扩展来构造一个新函数。没有其他对象会与此函数相等,只有 f == f 会返回 true,所有其他比较总是会产生 false。
  • @AndreyTyukin 我想他问的是比较函数引用,而不是函数本身。
  • @Tim 正如您在我的回答中看到的,这是我能想到的唯一普遍适用的解决方案。但这有点无聊,而且几乎毫无意义,因为很明显,您总是可以比较引用,这与函数无关。 val a = new AnyRef; val b = new AnyRef 也会给你a == a (true) 和a == b (false)...

标签: scala lambda equality


【解决方案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"
}

【讨论】:

    【解决方案2】:

    由于函数的外延相等(粗略地说:f 被认为“等于”g 当且仅当 f(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。

    【讨论】:

    • 现在变得有趣了。有什么错误吗?
    • 至少,我看不出它与was told here 有何矛盾。 Jörg W Mittag 甚至勾勒出了为什么外延函数相等性必须是不可判定的证明......
    • 我怀疑如果提问者知道什么是“扩展相等”,他一开始就不需要这个问题,所以扩展它会很有用。
    • @AlexeyRomanov 是的。但我只是想输入一些 OP 可以用谷歌搜索的关键字(如果他愿意的话)。我不想花太多时间在定义和解释上,因为我怀疑 OP 无论如何都希望引用平等,因为其他一切都会很快变得相当复杂。无论如何,在引言中添加了一个非常简短的解释,只是为了强调函数还有其他有意义的“平等”概念。
    猜你喜欢
    • 1970-01-01
    • 2018-11-29
    • 1970-01-01
    • 1970-01-01
    • 2018-02-05
    • 1970-01-01
    • 1970-01-01
    • 2012-06-05
    • 1970-01-01
    相关资源
    最近更新 更多