2012-10-04 39 views
10

Làm thế nào bạn có thể so sánh hai giá trị hàm Scala cho sự bình đẳng. Trường hợp sử dụng là tôi có một danh sách các hàm mà danh sách có thể chứa các bản sao và tôi chỉ muốn thực hiện từng hàm một lần.Làm thế nào để so sánh các giá trị hàm Scala cho sự bình đẳng

Nếu tôi có:

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

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

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

Nếu tôi cố gắng để so sánh chức năng với một trong hai == hoặc eq, tôi sẽ nhận được false trong cả hai trường hợp:

scala> f1 == f2 
res0: Boolean = false 

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

Đó là vấn đề không thể giải quyết nói chung. http://en.wikipedia.org/wiki/First-class_function#Equality_of_functions – missingfaktor

Trả lời

15

câu trả lời ngắn gọn: Đó là điều không thể.

Câu trả lời dài hơn: Bạn có thể có một số loại nhà máy chức năng đảm bảo rằng các hàm "giống hệt" giống hệt nhau một đối tượng. Tùy thuộc vào kiến ​​trúc của ứng dụng của bạn, điều đó có thể không khả thi.

8

Tôi muốn mở rộng một chút về câu trả lời của Kim và đưa ra một ví dụ về cách đạt được khả năng so sánh giới hạn các giá trị hàm.

Nếu bạn có một số định nghĩa mô tả về chức năng của mình, bạn có thể kiểm tra sự bình đẳng trên mô tả này. Ví dụ, bạn có thể định nghĩa một lớp (không phải là một lớp oo) của hàm số học đơn giản theo cách sau:

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} 

Với thiết lập này, nơi một ArthFun được xác định bởi lớp và các thành viên của nó, bạn có thể kiểm tra sự bình đẳng giá trị của loại ArthFun chỉ đơn giản bằng đối tượng bình đẳng như được xác định bởi lớp vỏ.

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

Tôi thích câu trả lời này, nhưng không thích phải định nghĩa một lớp cho mọi toán tử. Có một loại ma thuật vĩ mô nào có thể làm được điều này (nó biến các biểu thức thành các đối tượng lớp với nhiều kiểu trang trí khác nhau, chẳng hạn như bình đẳng.) – user48956

Các vấn đề liên quan