2012-01-05 31 views
5

Tôi là một chút bối rối bởi sự khác biệt về kiểu kiểm tra giữa cà ri và chức năng chung uncurried:Hợp nhất loại chung: nhiều tham số (T, T) so với nhiều danh sách tham số (T) (T)?

scala> def x[T](a: T, b: T) = (a == b) 
x: [T](a: T, b: T)Boolean 
scala> def y[T](a: T)(b: T) = (a == b) 
y: [T](a: T)(b: T)Boolean 

trực giác của tôi là cả hai x(1, "one")y(1)("one") nên cung cấp cho các lỗi loại, nhưng tôi đã sai:

scala> x(1, "one") 
res71: Boolean = false 
scala> y(1)("one") 
<console>:9: error: type mismatch; 
found : java.lang.String("one") 
required: Int 
       y(1)("one") 
       ^

Lúc đầu, tôi nghĩ là có một số loại đúc tiềm ẩn xảy ra, nhưng điều đó dường như không phải là trường hợp:

scala> x(1 :Int, "one" :String) 
res73: Boolean = false 

Vì vậy, những gì đang xảy ra? Trực giác của tôi nên là gì?

+0

Tôi đã nhìn thấy một bản sao của điều này một thời gian dài trước đây. Tôi cũng tin rằng trường hợp chính xác [gần như] này được ghi lại trong SLS. –

+0

Có, chúng tôi đi. Tôi đã cập nhật tiêu đề với thuật ngữ quan trọng "nhiều danh sách tham số", được thảo luận trong SLS :) –

Trả lời

9

Tôi nghĩ rằng trong trường hợp đầu tiên nó là upcasting (downcasting?) Cả hai đối số như vậy mà T: Bất kỳ. Trong lần thứ hai, nó là currying cho Int, và sau đó thất bại trên String.

Điều này có vẻ chịu tôi ra:

scala> y(1)_ 
res1: Int => Boolean = <function1> 
+0

Ok, có vẻ như có khả năng, cho rằng 'y (1: Any) (" hello ")' trả về 'false'. – rampion

+0

Xem bản chỉnh sửa của tôi để biết thêm một số bằng chứng về điều này –

+0

Như một lưu ý thú vị, câu hỏi này dường như gọi trong xác nhận được thực hiện ở đây: http://www.scala-lang.org/node/262 rằng "sau đó f (x) (y) và g (x, y) được biên dịch thành chính xác cùng một mã. " –

10

Scala cố gắng xác định loại một khối tham số cùng một lúc. Bạn có thể thấy điều này nếu bạn thêm tham số khác và một phần áp dụng:

def x[T](a: T, b: T)(c: T) = (a == b) 
scala> x(1, "one") _ 
res0: Any => Boolean = <function1> 

Tất nhiên, cả hai IntString được Any (và == được định nghĩa trên Any).

Loại thông số mà không được sử dụng trong một khối trước đó vẫn còn tự do để được sử dụng trong một khối sau:

def y[T,U](a: T)(b: U)(c: (T,U)) = (a == b) 
scala> y(1)("one") 
res1: (Int, java.lang.String) => Boolean = <function1> 

Bạn cũng có thể sử dụng các khối trước đó như các giá trị mặc định trong khối sau!

def z[T,U](a: T)(b: U)(c: (T,U) = (a,b)) = (c._1 == c._2) 
scala> z(1)("one")() 
res2: Boolean = false 

Do đó, phân phối các tham số của bạn trong nhiều khối tham số có hậu quả cho suy luận kiểu và mặc định (và cho một phần ứng dụng).

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