2012-04-24 18 views
6

Với một kiểu dữ liệu ví dụ với cú pháp kỷ lục:mẫu phù hợp vs chức năng cú pháp đăng ký cuối cùng khai thác lĩnh vực kiểu dữ liệu

data VmInfo = VmInfo {infoVid :: String 
        ,infoIndex :: Int 
        ,infoPid :: Int 
        ,infoExe :: String 
        } deriving (Show) 

và (vmInfo :: String -> VmInfo) chức năng mà tạo ra và trả về cấu trúc dữ liệu trên cho tên vm dưới dạng chuỗi.

Tôi có thể thấy hai phương pháp để trích xuất các phần riêng lẻ của loại dữ liệu VmInfo.

(VmInfo vid _ _ _) <- vmInfo vm 

Chỉ là mẫu phù hợp. Và ...

vid <- infoVid <$> vmInfo vm 

bằng cách sử dụng chức năng tạo trình biên dịch cú pháp ghi.

Câu hỏi rất đơn giản: đó là phương pháp ưa thích?

Số tiền đánh máy khôn ngoan, chúng giống nhau nên tôi đang tìm kiếm tốc độ và tính chính xác/thực hành tốt nhất.

Tôi giả định kết hợp mẫu sẽ nhanh hơn nhưng sau đó cú pháp ghi điểm là gì?

Cảm ơn.

+1

Tôi tin rằng cú pháp bản ghi được biến thành phiên bản khớp mẫu bởi trình biên dịch, do đó sẽ không có sự khác biệt về tốc độ. – ricochet1k

Trả lời

8

Đây không phải là ngữ nghĩa tương đương.

Hãy nhìn vào ví dụ đầu tiên:

(VmInfo vid _ _ _) <- vmInfo vm 

này thực hiện một mô hình phù hợp trong hoạt động ràng buộc. Có hai kết quả này. Đầu tiên là hàm tạo của kết quả của hành động vmInfo vm được đánh giá. Điều này có nghĩa là nếu vmInfo kết thúc bằng một dòng như return undefined, ngoại lệ được ném bằng cách đánh giá undefined sẽ xảy ra tại đối sánh mẫu này, không phải sau này sử dụng vid. Thứ hai là nếu khớp mẫu bị từ chối (mẫu khớp không khớp với giá trị), cá thể fail của đơn nguyên sẽ được gọi với văn bản lỗi khớp mẫu. Điều đó là không thể trong trường hợp này, nhưng nó thường có thể khi mô hình phù hợp với một hàm tạo trong một ràng buộc.

Bây giờ, trên để ví dụ tiếp theo:

vid <- infoVid <$> vmInfo vm 

Bằng cách định nghĩa của <$>, điều này sẽ được hoàn toàn lười biếng trong giá trị được trả về bởi các hành động (không ảnh hưởng). Nếu vmInfo kết thúc bằng return undefined, bạn sẽ không nhận được ngoại lệ từ việc đánh giá undefined cho đến khi bạn làm điều gì đó đã sử dụng giá trị vid. Ngoài ra, nếu infoVoid có khả năng ném bất kỳ ngoại lệ nào, chúng sẽ không xảy ra cho đến khi sử dụng vid, trường hợp tốt nhất.

Điều thú vị là, những khác biệt này chỉ xuất hiện trong phạm vi liên kết đơn thuần. Nếu vmInfo là thuần túy và bạn đã ràng buộc tên vid bên trong một biểu thức let hoặc where, chúng sẽ tạo mã giống hệt nhau.

Trong trường hợp đó, bạn muốn sử dụng công cụ nào tùy thuộc vào bạn. Cả hai đều là Haskell thành ngữ. Mọi người thường chọn bất cứ điều gì có vẻ tốt hơn trong bối cảnh họ đang làm việc.

Lý do chính khiến mọi người sử dụng hàm truy nhập là ngắn gọn khi bản ghi có nhiều trường khớp với mẫu rất lớn và vì chúng là hàm thực tế - chúng có thể được chuyển đến bất kỳ hàm bậc cao nào phù hợp với chúng. Bạn không thể vượt qua các trận đấu mẫu như một cấu trúc riêng biệt.

+6

Một lý do khác để sử dụng các trình truy cập so khớp mẫu là làm cho mã mạnh hơn một chút so với việc thay đổi cấu trúc dữ liệu khi chương trình được duy trì. Nếu bạn thay đổi cấu trúc dữ liệu theo bất kỳ cách nào, thường thì tất cả các đối sánh mẫu sẽ không biên dịch được. Nếu bạn chỉ xử lý một số lượng nhỏ các trường cùng lúc với nhiều trường, thì khi sử dụng các trình truy cập có nghĩa là các thay đổi đối với cấu trúc dữ liệu có khả năng chủ yếu chỉ ảnh hưởng đến các địa điểm sử dụng các trường bạn đã thêm/xóa/thay đổi. – Ben

+6

@Ben Để có được ưu điểm của cả hai, 'VmInfo {infoVid = vid} <- vmInfo vm'. –

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