Scala 函数相等概念

Scala 函数相等概念,scala,Scala,Scala中有函数相等的概念吗 scala> def foo(x: Int) = x + 1 foo: (x: Int)Int scala> def bar(x: Int) = x + 1 bar: (x: Int)Int 所以我不能对函数调用= scala> foo == bar <console>:10: error: missing arguments for method foo; follow this method with `_' if you w

Scala中有函数相等的概念吗

scala> def foo(x: Int) = x + 1
foo: (x: Int)Int

scala> def bar(x: Int) = x + 1
bar: (x: Int)Int
所以我不能对函数调用
=

scala> foo == bar
<console>:10: error: missing arguments for method foo;
follow this method with `_' if you want to treat it as a partially applied
 function
              foo == bar
              ^
/** Decides whether `f1` and `f2` compute the same function. */
def functionEquals[A, B](f1: A => B, f2: A => B): Boolean
scala>foo==bar
:10:错误:缺少方法foo的参数;
如果要将此方法视为部分应用的,请使用“\”遵循此方法
功能
foo==巴
^

除了验证所有x
foo(x)
=
bar(x)
(不确定如何做),我还可以如何验证相等性?

你不会真的期望
=
产生除false以外的任何结果,因为
=
意味着“具有相同的内存地址”除非专门为该类定义。毕竟,

scala> class A
scala> (new A) == (new A)
res0: Boolean = false
如果
Function1
尝试提供
=
的实现,那么不清楚它将检查什么。所有可能输入下的结果相同吗?同样的行为?相同的字节码

如果您想要一个具有定义良好的相等操作的函数类,您必须自己编写它:

class Adder(private val toAdd: Int) extends (Int => Int) {
  override def apply(n: Int) = n + toAdd

  override def equals(other: Any) = other match {
    case o: Adder => this.toAdd == o.toAdd
    case _ => false
  }
}
然后你可以做:

scala> val foo = new Adder(1)
foo: Adder = <function1>

scala> val bar = new Adder(1)
bar: Adder = <function1>

scala> foo(2)
res4: Int = 3

scala> foo == bar
res5: Boolean = true

您不会真的期望
==
产生除false之外的任何结果,因为
==
意味着“具有相同的内存地址”,除非它是专门为该类定义的。毕竟,

scala> class A
scala> (new A) == (new A)
res0: Boolean = false
如果
Function1
尝试提供
=
的实现,那么不清楚它将检查什么。所有可能输入下的结果相同吗?同样的行为?相同的字节码

如果您想要一个具有定义良好的相等操作的函数类,您必须自己编写它:

class Adder(private val toAdd: Int) extends (Int => Int) {
  override def apply(n: Int) = n + toAdd

  override def equals(other: Any) = other match {
    case o: Adder => this.toAdd == o.toAdd
    case _ => false
  }
}
然后你可以做:

scala> val foo = new Adder(1)
foo: Adder = <function1>

scala> val bar = new Adder(1)
bar: Adder = <function1>

scala> foo(2)
res4: Int = 3

scala> foo == bar
res5: Boolean = true

首先,在可以计算的函数上没有一般的等式关系(因为函数本质上是无限集)。根据函数的表示形式,您可能会得到弱相等(即,当结果为真时,两个参数相等,但当结果为假时,两个参数也可能相等)

在scala中,您可以执行以下操作:

scala> (foo _).equals((bar _ ))
res3: Boolean = false

scala> (foo _) == ((foo _ ))
res5: Boolean = false
函数后面的下划线是区分零参数应用程序和函数值的语法要求。equals方法(作为==)是通用的对象相等,因此只是通过引用进行比较。每次求值都会产生一个新的引用(闭包实例)。因此,平等性很弱:

scala> val x = foo _
x: Int => Int = <function1>

scala> x.equals(x)
res7: Boolean = true
scala>val x=foo_
x:Int=>Int=
scala>x.equals(x)
res7:Boolean=true

首先,在可以计算的函数上没有一般的等式关系(因为函数本质上是无限集)。根据函数的表示形式,您可能会得到弱相等(即,当结果为真时,两个参数相等,但当结果为假时,两个参数也可能相等)

在scala中,您可以执行以下操作:

scala> (foo _).equals((bar _ ))
res3: Boolean = false

scala> (foo _) == ((foo _ ))
res5: Boolean = false
函数后面的下划线是区分零参数应用程序和函数值的语法要求。equals方法(作为==)是通用的对象相等,因此只是通过引用进行比较。每次求值都会产生一个新的引用(闭包实例)。因此,平等性很弱:

scala> val x = foo _
x: Int => Int = <function1>

scala> x.equals(x)
res7: Boolean = true
scala>val x=foo_
x:Int=>Int=
scala>x.equals(x)
res7:Boolean=true
Scala中有函数相等的概念吗

scala> def foo(x: Int) = x + 1
foo: (x: Int)Int

scala> def bar(x: Int) = x + 1
bar: (x: Int)Int
简短且有点无用的答案是否定的,你不能根据赖斯定理写出函数的一般等式。推断两个函数是否相等需要证明函数中的逻辑,这在某些情况下可以做到,但在一般情况下不能做到

作为一个愚蠢的例子,考虑这样一个事实,我们知道任何一个偶数(可表示为2×n)的模数二等于零剩余,这是从小学数学中得到的微不足道的结果,但这是一个知识,编译器需要假设地决定Foo==Bar。< /P>

def foo(x: Int) = (x*2) % 2
def bar(x: Int) = 0
Scala的类型系统可以使用更复杂的类型对其中一些属性进行编码,但一般来说不是这样

Scala中有函数相等的概念吗

scala> def foo(x: Int) = x + 1
foo: (x: Int)Int

scala> def bar(x: Int) = x + 1
bar: (x: Int)Int
简短且有点无用的答案是否定的,你不能根据赖斯定理写出函数的一般等式。推断两个函数是否相等需要证明函数中的逻辑,这在某些情况下可以做到,但在一般情况下不能做到

作为一个愚蠢的例子,考虑这样一个事实,我们知道任何一个偶数(可表示为2×n)的模数二等于零剩余,这是从小学数学中得到的微不足道的结果,但这是一个知识,编译器需要假设地决定Foo==Bar。< /P>

def foo(x: Int) = (x*2) % 2
def bar(x: Int) = 0

Scala的类型系统可以使用更复杂的类型对这些属性中的一些进行编码,但一般来说不是这样。

假设存在这样一个函数

scala> foo == bar
<console>:10: error: missing arguments for method foo;
follow this method with `_' if you want to treat it as a partially applied
 function
              foo == bar
              ^
/** Decides whether `f1` and `f2` compute the same function. */
def functionEquals[A, B](f1: A => B, f2: A => B): Boolean
然后我们可以写下:

/** Decides whether `m` halts on input `x`. */
def halts[X](m: X => Unit, x: X): Boolean = 
  !functionEquals[Unit, Unit](
    { _ => while(true)() },
    { _ => m(x) }
  )

当然,这是不可能的。

假设存在这样一个函数

scala> foo == bar
<console>:10: error: missing arguments for method foo;
follow this method with `_' if you want to treat it as a partially applied
 function
              foo == bar
              ^
/** Decides whether `f1` and `f2` compute the same function. */
def functionEquals[A, B](f1: A => B, f2: A => B): Boolean
然后我们可以写下:

/** Decides whether `m` halts on input `x`. */
def halts[X](m: X => Unit, x: X): Boolean = 
  !functionEquals[Unit, Unit](
    { _ => while(true)() },
    { _ => m(x) }
  )

这当然是不可能的。

TLDR:是的,有函数相等的概念。但它是基本的对象引用相等,因此没有什么好处

  • 问题1:您可以在函数VAL上调用==但DEF不是VAL。

    不能在DEF上调用任何方法(函数应用程序的特殊情况除外),因为它们不是对象实例(VAL)。但您可以通过调用它们(应用),为缺少的参数指定u(创建部分应用的函数),将它们转换为VAL:

  • 问题2:Function1未定义equals()覆盖

    函数1
    定义不覆盖
    等于
    Function1
    扩展了
    AnyRef
    ,从而继承了==/equals/eq的功能:

    • Any.==
      只需委托给
      Any.equals
    • AnyRef.equals
      只是委托给
      AnyRef.eq
      ,这是检查对象引用的等价性
    因此,Function1.==意味着