2012-10-04 23 views
10

Eşitlik için iki Scala işlev değerini nasıl karşılaştırabilirsiniz? Kullanım durumu, listenin çiftleri içerebileceği bir işlevler listesine sahip olduğum ve yalnızca her işlevi bir kez yürütmek istediğim.Eşitlik için Scala işlev değerleri nasıl karşılaştırılır

ben varsa:

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

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

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

Ben == veya eq biriyle işlevini karşılaştırmak çalışırsanız, ben her iki durumda da false alacak:

scala> f1 == f2 
res0: Boolean = false 

scala> f1 eq f2 
res1: Boolean = false 
+10

Genel olarak kabul edilemez bir problemdir. http://en.wikipedia.org/wiki/First-class_function#Equality_of_functions – missingfaktor

cevap

15

Kısa cevap: Bu mümkün değil.

Daha uzun yanıt: "özdeş" işlevlerin aynı nesne olmasını sağlayan bir işlev fabrikanız olabilir. Uygulamanızın mimarisine bağlı olarak, bu mümkün olmayabilir.

8

Kim'in cevabını biraz açıklığa kavuşturmak ve işlev değerlerinin sınırlı karşılaştırılabilirliğine nasıl ulaşılacağına dair bir örnek vermek istiyorum.

İşlevinizin bir tür tanımlayıcı tanımına sahipseniz, bu açıklamada eşitlik olup olmadığını kontrol etmek mümkündür. Örneğin, aşağıdaki şekilde basit aritmetik fonksiyonları bir sınıf (değil bir oo sınıfı) tanımlayabilirsiniz:

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} 

bir ArthFun sınıfının ve üyeleri tarafından tanımlanır bu kurulum, ile, eşitlik kontrol edebilirsiniz ArthFun türündeki değerlerin basitçe, vaka sınıfı tarafından tanımlandığı gibi nesne eşitliği ile.

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) 
+0

Bu cevabı beğeniyorum, ancak her operatör için bir sınıf tanımlamaktan hoşlanmıyorum. Bunu yapabilecek bir çeşit makro büyü var mı (ifadeleri, eşitlik gibi çeşitli süslemelerle sınıf nesnelerine dönüştürür.) – user48956

İlgili konular