2015-07-13 19 views
6

Trong sách "lập trình hàm trong Scala", nó mang lại cho một vài ví dụ về "tác dụng phụ", một trong số họ là những gì:Tại sao "đọc từ một tệp" không phải là chức năng thuần túy?

  • Đọc từ hoặc văn bản cho một tập tin

Tôi có thể hiểu "viết vào một tập tin" không phải là tinh khiết, bởi vì nó thay đổi môi trường. Nhưng tại sao "đọc một tập tin" không phải là tinh khiết? Nó không thay đổi gì cả.

Xem ví dụ của tôi:

val readFile: File => String = file => readingTheContentFromFile(file) 
+1

Bạn đã xem xét cách đọc chỉ một phần của tệp thay đổi "con trỏ đọc" của tệp hay bạn chỉ quan tâm đến việc đọc toàn bộ tệp và giả sử nội dung của tệp luôn giống nhau (nghĩa là, phải thừa nhận rằng, Một Quãng)? –

+0

có thể trùng lặp của [Có phải chức năng thuần túy nếu nó đọc một số dữ liệu từ bên ngoài thay vì tham số?] (Http://stackoverflow.com/questions/31376933/is-it-a-pure-function-if-it-reads -Một số-dữ liệu-từ-bên ngoài-thay-hơn-tham số) –

Trả lời

13

Một chức năng tinh khiết allways trả về giá trị tương tự cho cùng một đầu vào. Nếu không, nó dựa trên các tác dụng phụ (như thay đổi một tập tin). Nếu bạn đọc từ một tập tin, kết quả có thể thay đổi mà không có các tham số cho hàm thay đổi.

Khái niệm liên quan là 'minh bạch tham chiếu'. Điều này có nghĩa là bạn có thể thay thế một cuộc gọi hàm và một tập các tham số đã cho với kết quả mà hàm sẽ trả về. Đọc từ một tập tin do đó không phải là tham chiếu trong suốt!

+0

Có, một hàm thuần túy chỉ có thể thay đổi khi các tham số của nó thay đổi. Nếu nó đọc từ một tập tin, tập tin đó có thể thay đổi độc lập với các tham số chức năng. –

2

Trong lập trình chức năng, một chức năng là pure nếu

  1. Chức năng luôn đánh giá các giá trị kết quả tương tự cho các giá trị tham số tương tự (s). Giá trị kết quả chức năng 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 trong khi thực hiện chương trình số tiền thu được hoặc giữa các lần thực hiện khác nhau của chương trình hoặc cũng không thể phụ thuộc vào bất kỳ đầu vào bên ngoài nào từ thiết bị I/O.
  2. Đánh giá kết quả không gây ra bất kỳ tác dụng phụ 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 đầu ra đến thiết bị I/O.

I/O can be modelled in a pure way nếu

  1. chuỗi các hoạt động trên các thiết bị I/O có liên quan được mô phỏng một cách rõ ràng như cả một cuộc tranh cãi và kết quả là, và
  2. I/O hoạt động được thực hiện thất bại khi chuỗi đầu vào không mô tả các hoạt động thực sự được thực hiện kể từ khi chương trình bắt đầu thực hiện .

Đó là, thay vì thực sự đọc từ một tập tin, bạn sẽ có được "nội dung tập tin của" như một tham số, và thay vì thực sự bằng văn bản cho một tập tin, bạn trở về "đầu ra tập tin của" như một giá trị. Điều này có vẻ là một bài tập suy nghĩ trong hầu hết các ngôn ngữ thực tế.

6

Nếu một chức năng là tinh khiết, sau đó nó luôn luôn là an toàn để thực hiện common subexpression elimination ví dụ: bạn có thể thay thế các mã giả sau

do { 
    x = readFile "file.txt" 
    writeFile "file.txt" "Goodbye" 
    return (x + readFile "file.txt") 
} 

với

do { 
    x = readFile "file.txt" 
    writeFile "file.txt" "Goodbye" 
    return (x + x) 
} 

và bạn sẽ nhận được kết quả tương tự.Nhưng rõ ràng, vì cuộc gọi đến writeFile xuất hiện giữa hai cuộc gọi đến readFile trong ví dụ đầu tiên, đây không phải là một chuyển đổi an toàn để thực hiện và do đó chức năng không thuần túy.

+0

Cảm ơn, đó là một ví dụ tốt! – Freewind

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