2012-02-24 22 views
6

Khi cố gắng trả lời câu hỏi này: Leave off underscore in function literal Tôi đã cố gắng viết mã ví dụ và tôi phải đối mặt với một hành vi lạ.Scala: kết quả nghịch đảo khi thoát dấu gạch dưới với :::

scala> val myList = 1::2::Nil 
myList: List[Int] = List(1, 2) 

scala> def concat:(List[Int]=> List[Int]) = myList::: 
concat: (List[Int]) => List[Int] 

scala> concat(3::Nil) 
res1: List[Int] = List(3, 1, 2) 

Khi tôi có câu trả lời hay khi sử dụng các cú pháp _ hoặc x=> f(x).

scala> def concat0:(List[Int]=> List[Int]) = x=> myList:::x 
concat0: (List[Int]) => List[Int] 

scala> def concat1:(List[Int]=> List[Int]) = myList::: _ 
concat1: (List[Int]) => List[Int] 

scala> concat0(3::Nil) 
res2: List[Int] = List(1, 2, 3) 

scala> concat1(3::Nil) 
res3: List[Int] = List(1, 2, 3) 

Có một lời giải thích hợp lý tại sao myList đưa ra sau khi 3::Nil trong hàm concat?

Trả lời

7

myList ::: _ chuyển thành _.:::(myList), trong khi myList ::: chuyển thành myList.:::(_).

tl; dr

This post đi vào chi tiết hơn về các phương pháp kết hợp đúng đắn. Có gì xảy ra ở đây là:

  • def concat0:(List[Int]=> List[Int]) = x=> myList:::x
    • Scala trình biên dịch có thể suy ra rằng x nếu loại List[Int]
    • List có một phương pháp :::
    • Bởi vì các quy tắc của associativity đúng, điều này biến thành x.:::(myList) , được thêm vào myList đến x.
  • def concat: (Danh sách [Int] => Danh sách [Int]) = myList :::
    • myList nếu loại List[Int]
    • Không có phía bên tay phải của :::, do đó không có sự liên kết bên phải
    • Thay vào đó, trình biên dịch sẽ nhập a. giữa myList:::
    • myList.::: tương tự như x => myList.:::(x), chuẩn bị trước x đến myList.
+0

Cảm ơn bài đăng thực sự chi tiết và rõ ràng. –

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