2013-04-08 33 views
7

Giả sử tôi đã hai F # chức năng:Làm cách nào để biết chức năng F # có thuần túy không?

let sq x = x*x 

let tm = DateTime.Now 

SQ Rõ ràng là tinh khiết ở chỗ nó sẽ luôn luôn trả về giá trị tương tự cho một đầu vào cho trước khi tm là không tinh khiết bởi vì nó sẽ trả về một giá trị khác nhau mỗi lần nó được gọi là .

Nói chung có cách nào để xác định xem một hàm cụ thể trong F # là thuần túy hay không tinh khiết mà không phân tích những gì nó làm, nói cách khác đọc nó theo từng dòng?

Ngoài ra, có cách nào để chú thích một hàm để báo cho trình biên dịch biết rằng hàm này là thuần khiết hay không tinh khiết khi bạn viết nó?

Cuối cùng khi gọi một hàm là một phần của thời gian chạy ngôn ngữ chung (chẳng hạn như DateTime), làm thế nào người ta có thể biết nó là tinh khiết hay không tinh khiết mà không thử nó?

Lưu ý: do "tinh khiết" Ý tôi là định nghĩa từ Wikipedia: http://en.wikipedia.org/wiki/Pure_function (permalink)

Trong lập trình máy tính, một chức năng có thể được mô tả như tinh khiết nếu cả hai các báo cáo về chức năng giữ:

  1. Hàm luôn đánh giá cùng một giá trị kết quả cho cùng một đối số giá trị. Giá trị kết quả của hàm không thể phụ thuộc vào bất kỳ thông tin ẩn hoặc trạng thái nào có thể thay đổi khi thực hiện chương trình số tiền thu được hoặc giữa các lần thực thi khác nhau của chương trình.

  2. Đánh giá kết quả không gây ra bất kỳ hiệu ứng hoặc đầu ra nào có thể quan sát được , chẳng hạn như đột biến đối tượng có thể thay đổi hoặc xuất ra thiết bị I/O.

+1

Khi bạn nói thuần khiết, bạn có thực sự ngụ ý idempotent? Hay bạn có nghĩa là nó không gây ra tác dụng phụ nào? –

+1

Ah, vì vậy Wikipedia nói cả hai. Đủ công bằng.FWIW, tôi không nghĩ Microsoft cung cấp bất kỳ loại chú thích hoặc thuộc tính nào đánh dấu các chức năng là "thuần khiết ..." Bạn chỉ cần biết. –

+0

Bạn cũng có thể tìm thấy câu trả lời cho câu hỏi này http://stackoverflow.com/questions/4391524/is-returning-a-random-value-from-function-a-side-effect đọc có giá trị. –

Trả lời

9

F # không cung cấp bất kỳ tính năng và công cụ để kiểm tra xem phương pháp này thuần túy, do đó, một câu trả lời đơn giản là bạn phải kiểm tra khách sạn này cho mình.

Ngoài F #, cần lưu ý rằng thư viện Code Contracts có khái niệm về phương pháp thuần túy (và chúng có thể được đánh dấu bằng PureAttribute), nhưng tôi không hoàn toàn chắc chắn câu chuyện kiểm tra ở đó là gì. Tôi nghĩ rằng các hợp đồng mã đi kèm với kiểm tra tĩnh phân tích IL (và nên làm việc cho F # quá), nhưng đây là nhiệm vụ khá khó khăn, vì vậy tôi mong đợi nó sẽ được khá hạn chế. Tuy nhiên, các PureAttribute được sử dụng trên một số phương pháp BCL, vì vậy bạn có thể nói rằng một số tiêu chuẩn. NET phương pháp là tinh khiết.

+5

'PureAttribute' chỉ là một cách để nói cho các hợp đồng mã rằng hàm là thuần túy - không có phân tích (thời gian chạy hoặc tĩnh) được thực hiện – AlexFoxGill

+3

Thật không may, các hợp đồng mã [vẫn] (http://social.msdn.microsoft.com/Forums/ en-US/11b8c5e3-a25d-4770-a46d-14f24921e0a0/f-và-mã-hợp đồng? forum = codecontracts) [không] (http://social.msdn.microsoft.com/Forums/en-US/ 7830b49c-ff45-4105-8609-1e2f8b81263d/khi-sẽ-f-được hỗ trợ? Forum = codecontracts) làm việc với F #. –

1

Về mặt kỹ thuật, giá trị 'tm' của bạn không phải là hàm, nhưng giá trị của loại DateTime và không thay đổi, vì vậy mỗi lần bạn đánh giá giá trị này sau khi tạo giá trị sẽ luôn giống nhau.

+2

... và để làm rõ hơn nữa, nếu bạn nói let tm() = DateTime.Now (lưu ý thêm dấu ngoặc), bạn sẽ buộc nó trở thành một chức năng có thể là ý định của bạn. – Kit

0

Giả sử có thể xác định cả hàm thuần, inpure trong f #, tôi sẽ ngạc nhiên nếu có thuật toán có thể kiểm tra mã f # (định nghĩa hàm) cho độ tinh khiết - kiểm tra mã chương trình cho thuộc tính ngữ nghĩa nói chung không thể xác định được bằng định lý của Rice.

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