13

2つのScala関数の値を比較して等しいかどうかを確認するにはどうすればよいですか。ユースケースは、リストに重複を含めることができる関数のリストがあり、各関数を1回だけ実行したい場合です。

私が持っている場合:

scala> object A {
     |   def a {}
     | }
defined module A

scala> val f1 = A.a _
f1: () => Unit = <function0>

scala> val f2 = A.a _
f2: () => Unit = <function0>

関数をまたはのいずれかと比較しようとすると、==どちらの場合も次のeqようになります。false

scala> f1 == f2
res0: Boolean = false

scala> f1 eq f2
res1: Boolean = false
4

2 に答える 2

16

簡単な答え:それは不可能です。

より長い答え:「同一の」関数が実際に同じオブジェクトであることを保証するある種の関数ファクトリを持つことができます。ただし、アプリケーションのアーキテクチャによっては、それが実現できない場合があります。

于 2012-10-04T10:30:45.390 に答える
8

キムの答えを少し拡張し、関数値の限定された比較可能性を実現する方法の例を示したいと思います。

関数のある種の記述的な定義がある場合、この記述が等しいかどうかをチェックすることができます。たとえば、次の方法で単純な算術関数のクラス(ooクラスではない)を定義できます。

sealed trait ArthFun extends (Double => Double)
case class Mult(x: Double) extends ArthFun {def apply(y: Double) = x * y}
case class Add(x: Double) extends ArthFun {def apply(y: Double) = x + y}

この設定では、anArthFunがそのクラスとメンバーによってArthFun定義されているため、caseクラスで定義されているオブジェクトの同等性によって、型の値が同等であるかどうかを確認できます。

scala> trait ArthFun extends (Double => Double)
defined trait ArthFun

scala> case class Mult(y: Double) extends ArthFun { def apply(x: Double) = x * y; override def toString = "*" + y}
defined class Mult

scala> case class Add(y: Double) extends ArthFun { def apply(x: Double) = x + y; override def toString = "+" + y }
defined class Add

scala> Seq(Mult(5),Mult(4),Add(4),Add(3),Mult(5)).distinct
res4: Seq[Product with ArthFun with Serializable] = List(*5.0, *4.0, +4.0, +3.0)
于 2012-10-04T11:18:29.033 に答える