2010-12-12 8 views
19

Hãy tạo một giá trị vì lợi ích của câu hỏi này:Scala nhấn mạnh chức năng tối thiểu

val a = 1 :: Nil 

bây giờ, tôi có thể chứng minh rằng các chức năng ẩn danh có thể được viết dưới dạng viết tắt như thế này:

a.map(_*2) 

có thể viết một cách viết tắt của chức năng này không ?:

a.map((x) => x) 

giải pháp của tôi không hoạt động:

a.map(_) 
+0

Không có ý nghĩa nhiều, phải không? Nó chỉ là một NOP. – delnan

+0

đây chỉ là một ví dụ. nó có thể làm cho một số ý nghĩa trong bối cảnh – coubeatczech

+2

Đây là một ví dụ tốt về các trường hợp sử dụng quá mức (imho) của đường '_' ở Scala thực sự gây khó khăn cho mọi người khi chọn ngôn ngữ. – akauppi

Trả lời

20

hình thức viết tắt đầu tiên của bạn cũng có thể được viết point-free

a map (2*) 

Nhờ nhân là giao hoán.

Đối với (x) => x, bạn muốn có chức năng identity. Điều này được định nghĩa trong Predef và là chung chung, vì vậy bạn có thể chắc chắn rằng nó an toàn kiểu.

+3

Tôi nghĩ bạn có nghĩa là giao hoán. – Debilski

+2

Thật đáng tiếc là 'x => x' là bốn ký tự trong khi' danh tính' là tám. Đây là lý do tại sao tôi không bao giờ sử dụng 'danh tính'. –

+0

@debilski Công cụ này không dễ chút nào bạn biết! Không phải khi có một chiến đấu 18 tháng tuổi để truy cập vào bàn phím! –

15

Bạn nên sử dụng chức năng identity cho trường hợp sử dụng này.

a.map(identity) 

identity được định nghĩa trong scala.Predef như:

implicit def identity[A](x: A): A = x 
35

Để lưu nội dung, a.map(_) không hoạt động vì nó là viết tắt của x => a.map(x) và không phải là a.map(x => x). Điều này xảy ra vì một đơn _ thay cho thông số là viết tắt của hàm được áp dụng một phần. Trong trường hợp của 2*_, viết tắt của hàm ẩn danh. Hai cách sử dụng này rất gần nhau và rất phổ biến khi chúng bị nhầm lẫn.