2011-08-24 31 views
14

Giả sử bạn có những điều sau đây:Scala, tách lạng bộ và quá tải

foo(x: String)(y: Int): Int 
foo(x: String)(y: Double): Int 

Scala không cho phép biểu hiện như vậy. Theo như tôi có thể thấy, lý do cho điều này là foo ("asdf") không có một loại được xác định rõ ràng (đó là Int => Int hoặc Double => Int).

Có lý do nào khiến các chức năng "đa vai trò" đó không được phép?

+0

https://issues.scala-lang.org/browse/SI-2628 – Bradford

+0

Scala cho phép bạn xác định cặp phương thức quá tải đó, nhưng mọi cuộc gọi đều mơ hồ, vì những lý do được Martin nêu dưới đây. Có liên quan: http://stackoverflow.com/questions/2510108/why-avoid-method-overloading – retronym

Trả lời

19

Độ phân giải quá tải trong Scala chỉ mất danh sách tham số đầu tiên. Đó là lý do tại sao các lựa chọn thay thế phải khác nhau trong danh sách này. Có một lý do chính đáng cho việc này: Chúng tôi có thể sử dụng loại hàm được giải quyết để suy ra loại đối số tiếp theo. Điều này cho phép các thành ngữ như:

xs.corresponds(ys) { (x, y) => x < y } 

Lưu ý rằng ở đây chúng ta cần phải biết loại corresponds để suy ra các loại xy. Sẽ thật đáng tiếc khi điều này bị hỏng khi corresponds bị quá tải.

+0

Cảm ơn câu trả lời. Theo dõi, sẽ không thể có danh sách các loại có thể được gán cho x và y, dựa trên những gì các phiên bản quá tải tương ứng nằm trong phạm vi (tương tự như cách hoạt động của implicits) và chỉ quyết định loại chỉ khi bạn phải? Hoặc điều này có đi ngược lại ý tưởng gõ tĩnh? –

+0

@Martin Odersky Bạn có thấy http://stackoverflow.com/q/7291168 Cảm ơn bạn! –

+2

Bất kỳ phương pháp nào xem xét danh sách các loại có thể có nguy cơ nổ theo thời gian của các loại kiểm tra. Đó là lý do tại sao Scala thường không làm điều đó trong thuật toán suy luận kiểu của nó. –

2

Đây không phải là lần đầu tiên câu hỏi này được yêu cầu: it was asked back in 2009. Thật không may, Martin đã không nói rõ vấn đề là gì, ngoài ra nó sẽ đòi hỏi một sự thay đổi khá rộng rãi về cách hoạt động của quá tải. Tôi đã xem xét các spec và nó không rõ ràng với tôi, nơi các vấn đề cốt lõi nói dối, nhưng tôi không đủ kỹ năng trong spec để cung cấp cho một câu trả lời dứt khoát một trong hai cách.

+1

Đây là vấn đề hơi khác. Trong câu hỏi bạn liên kết đến, bạn có hai hàm, chỉ khác với kiểu trả về của chúng ('foo (x: Bar): Unit' so với' foo (x: Bar): Hàm1 [Bar => Baz, Unit] ') nếu lý do của tôi là chính xác (vẫn chưa hoàn toàn thuyết phục ...) – Dirk

+0

Tôi không hiểu tại sao _issue_ lại khác. Các điều kiện theo đó vấn đề được thể hiện có thể khác nhau nhưng tôi nghĩ vấn đề là như nhau. Tôi đã thử tất cả các loại thao tác nhưng lỗi không bao giờ thay đổi. Tôi đọc như là, quá tải được thực hiện rất sớm, hoặc được ưu tiên hơn "x". –

+0

Tôi không chắc chắn điều này là như nhau. Trong vấn đề scala bạn liên kết với, nó có ý nghĩa để có hai hàm, vì foo() và foo() _ là khác nhau, trong khi trong tình huống hiện tại, không có cách nào khác để biểu diễn hai hàm foo có thể() _ chức năng. Lý do cơ bản có thể giống nhau, nhưng tôi không bị thuyết phục. Tôi nghĩ đó cũng là điểm của Dirk. –

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