Tôi không có bằng tiến sĩ, cũng không có loại bằng cấp nào khác về CS cũng không phải toán cũng như bất kỳ lĩnh vực nào khác. Tôi không có kinh nghiệm trước với Scala cũng như bất kỳ ngôn ngữ tương tự nào khác. Tôi không có kinh nghiệm với các hệ thống loại so sánh từ xa. Trong thực tế, ngôn ngữ duy nhất mà tôi có nhiều hơn là một kiến thức hời hợt trong đó thậm chí có một hệ thống loại là Pascal, không được biết đến chính xác với hệ thống loại tinh vi của nó. (Mặc dù nó không có các loại phạm vi, mà AFAIK khá nhiều ngôn ngữ không khác có, nhưng đó không phải là thực sự liên quan ở đây.) Ba ngôn ngữ khác mà tôi biết là BASIC, Smalltalk và Ruby, không ai trong số đó thậm chí còn có một hệ thống kiểu.
Tuy nhiên, tôi không gặp khó khăn gì trong việc hiểu chữ ký của mapchức năng bạn đã đăng. Dường như với tôi khá giống chữ ký mapcó trong mọi ngôn ngữ khác mà tôi từng thấy. Sự khác biệt là phiên bản này là chung chung hơn. Nó trông giống như một thứ C ++ STL hơn là, nói, Haskell. Cụ thể, nó trừu tượng ra khỏi loại bộ sưu tập cụ thể bằng cách chỉ yêu cầu đối số đó IterableLikevà cũng trừu tượng khỏi loại trả về cụ thể bằng cách chỉ yêu cầu tồn tại một hàm chuyển đổi ẩn có thể tạo ra thứ gì đó từ tập hợp các giá trị kết quả đó. Vâng, điều đó khá phức tạp, nhưng nó thực sự chỉ là một biểu hiện của mô hình chung về lập trình chung: đừng cho rằng bất cứ điều gì bạn không thực sự phải làm.
Trong trường hợp này, mapthực sự không cần bộ sưu tập là một danh sách, hoặc được sắp xếp hoặc có thể sắp xếp hoặc bất cứ thứ gì tương tự. Điều duy nhất mapquan tâm là nó có thể có quyền truy cập vào tất cả các yếu tố của bộ sưu tập, từng cái một, nhưng không theo thứ tự cụ thể. Và nó không cần biết bộ sưu tập kết quả là gì, nó chỉ cần biết cách xây dựng nó. Vì vậy, đó là những gì chữ ký loại của nó yêu cầu.
Vì vậy, thay vì
map :: (a → b) → [a] → [b]
Chữ ký kiểu truyền thống maplà gì, nó được khái quát hóa để không yêu cầu cụ thể Listmà chỉ là một IterableLikecấu trúc dữ liệu
map :: (IterableLike i, IterableLike j) ⇒ (a → b) → i → j
mà sau đó được khái quát hóa thêm bằng cách chỉ yêu cầu một hàm tồn tại có thể chuyển đổi kết quả thành bất kỳ cấu trúc dữ liệu nào mà người dùng muốn:
map :: IterableLike i ⇒ (a → b) → i → ([b] → c) → c
Tôi thừa nhận rằng cú pháp là một chút vụng về, nhưng ngữ nghĩa là như nhau. Về cơ bản, nó bắt đầu từ
def map[B](f: (A) ⇒ B): List[B]
đó là chữ ký truyền thống cho map. (Lưu ý làm thế nào do tính chất hướng đối tượng của Scala, tham số danh sách đầu vào biến mất, bởi vì giờ đây nó là tham số máy thu ngầm mà mọi phương thức trong một hệ thống OO gửi đơn có.) Sau đó, nó khái quát từ cụ thể Listsang tổng quát hơnIterableLike
def map[B](f: (A) ⇒ B): IterableLike[B]
Bây giờ, nó thay thế IterableLikebộ sưu tập kết quả bằng một hàm tạo ra , tốt, thực sự là về bất cứ thứ gì.
def map[B, That](f: A ⇒ B)(implicit bf: CanBuildFrom[Repr, B, That]): That
Mà tôi thực sự tin rằng không phải là điều đó khó có thể hiểu được. Thực sự chỉ có một vài công cụ trí tuệ mà bạn cần:
- Bạn cần biết (đại khái)
maplà gì . Nếu bạn chỉ đưa ra chữ ký loại mà không có tên của phương thức, tôi thừa nhận, sẽ khó hơn rất nhiều để tìm hiểu điều gì đang xảy ra. Nhưng vì bạn đã biết những gì mapcần phải làm và bạn biết chữ ký loại của nó là gì, bạn có thể nhanh chóng quét chữ ký và tập trung vào sự bất thường, như "tại sao điều này lại maplấy hai chức năng làm đối số chứ không phải một?"
- Bạn cần phải có khả năng thực sự đọc chữ ký loại. Nhưng ngay cả khi bạn chưa bao giờ thấy Scala trước đây, điều này khá dễ dàng, vì nó thực sự chỉ là một hỗn hợp các cú pháp loại mà bạn đã biết từ các ngôn ngữ khác: VB.NET sử dụng dấu ngoặc vuông cho đa hình tham số và sử dụng một mũi tên để biểu thị Kiểu trả về và dấu hai chấm để phân tách tên và loại, thực sự là chuẩn.
- Bạn cần biết đại khái về lập trình chung là gì. (Mà không phải là điều đó khó có thể tìm ra, vì nó về cơ bản tất cả các giải thích rõ ràng trong tên: nó theo nghĩa đen chỉ lập trình một cách chung chung).
Không ai trong số ba người này nên làm cho bất kỳ lập trình viên chuyên nghiệp hoặc thậm chí sở thích đau đầu nghiêm trọng. maplà một chức năng tiêu chuẩn trong hầu hết mọi ngôn ngữ được thiết kế trong 50 năm qua, thực tế là các ngôn ngữ khác nhau có cú pháp khác nhau nên rõ ràng đối với bất kỳ ai đã thiết kế trang web với HTML và CSS và bạn không thể đăng ký chương trình thậm chí từ xa danh sách gửi thư liên quan mà không có một số fanboy C ++ khó chịu từ nhà thờ St. Stepanov giải thích những ưu điểm của lập trình chung.
Vâng, Scala rất phức tạp. Vâng, Scala có một trong những hệ thống loại tinh vi nhất mà con người biết đến, cạnh tranh và thậm chí vượt qua các ngôn ngữ như Haskell, Miranda, Clean hoặc Cyclone. Nhưng nếu sự phức tạp là một lập luận chống lại sự thành công của ngôn ngữ lập trình, C ++ sẽ chết từ lâu và tất cả chúng ta sẽ viết Scheme. Có rất nhiều lý do khiến Scala rất có thể sẽ không thành công, nhưng thực tế là các lập trình viên không thể bận tâm để bật bộ não của họ trước khi ngồi xuống trước bàn phím có lẽ sẽ không phải là chính.