Tôi có cảm giác mình sẽ rất không được ưa chuộng khi nói những gì tôi định nói, nhưng cảm thấy tôi phải trả lời một số thông tin (theo ý kiến của tôi sai) được trình bày ở đây.
Mặc dù đúng là không an toànPerformIO đã được thêm chính thức vào ngôn ngữ như một phần của phụ lục FFI, lý do cho điều này phần lớn là lịch sử hơn là logic. Nó tồn tại không chính thức và được sử dụng rộng rãi lâu trước khi Haskell từng có FFI. Nó không bao giờ chính thức là một phần của tiêu chuẩn Haskell chính bởi vì, như bạn đã quan sát, nó chỉ là một sự bối rối. Tôi đoán hy vọng là nó sẽ biến mất vào một thời điểm nào đó trong tương lai, bằng cách nào đó. Điều đó đã không xảy ra, cũng không theo ý kiến của tôi.
Việc phát triển phụ lục FFI cung cấp một lý do thuận tiện cho việc không an toànPerformIO để nhận được tiêu chuẩn ngôn ngữ chính thức vì nó có vẻ không quá tệ ở đây, khi so sánh thêm khả năng gọi mã nước ngoài (IE C) trong đó tất cả mọi phiên cược đều có liên quan đến việc đảm bảo độ tinh khiết và độ an toàn tĩnh). Cũng thuận tiện khi đặt nó ở đây vì những lý do chính trị cơ bản. Nó nuôi dưỡng huyền thoại rằng Haskell sẽ tinh khiết, nếu chỉ có nó không phải cho tất cả những hệ điều hành "được thiết kế kém" hoặc "được thiết kế kém" hoặc phần cứng "được thiết kế kém" hay .. bất cứ điều gì .. unsafePerformIO thường được sử dụng với mã liên quan đến FFI, nhưng lý do cho việc này thường liên quan đến thiết kế xấu của FFI và thực sự là bản thân Haskell, không phải thiết kế xấu của bất cứ điều gì Haskell đang thử giao diện. Vì vậy, như Norman Ramsey nói, vị trí chính thức cho rằng OK khi sử dụng không an toànPerformIO cung cấp một số nghĩa vụ chứng minh đã được thỏa mãn bởi bất kỳ ai sử dụng nó (chủ yếu là làm điều này không làm mất hiệu lực các biến đổi trình biên dịch quan trọng như nội tuyến và phụ thường dùng). -xóa loại trừ). Cho đến nay rất tốt, hoặc như vậy người ta có thể nghĩ. Các kicker thực sự là những nghĩa vụ bằng chứng không thể được đáp ứng bởi những gì có lẽ là trường hợp sử dụng phổ biến nhất cho unsafePerformIO, mà theo ước tính của tôi chiếm hơn 50% của tất cả các unsafePerformIOs ra khỏi đó trong tự nhiên. Tôi đang nói về các thành ngữ kinh khủng được gọi là "unsafePerformIO hack" được chứng minh (trên thực tế rõ ràng) hoàn toàn không an toàn (trong sự hiện diện của nội tuyến và cse).
Tôi thực sự không có thời gian, không gian hoặc độ nghiêng để đi vào những gì "unsafePerformIO hack" là hoặc tại sao nó cần trong thư viện IO thực, nhưng dòng dưới cùng là người làm việc trên cơ sở hạ tầng Haskells IO thường "mắc kẹt giữa một tảng đá và một nơi khó khăn". Họ có thể cung cấp API an toàn vốn không có triển khai an toàn (Haskell) hoặc có thể cung cấp API không an toàn vốn có thể được triển khai một cách an toàn, nhưng những gì họ hiếm khi làm là cung cấp an toàn trong cả hai thiết kế API và.Đánh giá thông thường với "unsafePerformIO hack" xuất hiện trong mã thế giới thực (bao gồm cả các thư viện chuẩn Haskell), có vẻ như hầu hết chọn tùy chọn cũ là thấp hơn của hai tệ nạn, và hy vọng trình biên dịch sẽ không những thứ lên với nội tuyến, cse hoặc bất kỳ chuyển đổi nào khác.
Tôi ước tất cả điều này không phải như vậy. Tiếc là nó.
Về sửa đổi của bạn: Nhưng nó vẫn còn có thể tạo ra một thư viện chức năng có thể được gọi từ một chương trình bắt buộc. Cuối cùng, lập trình viên quyết định mức độ hiện diện của chức năng. –
Không thể giới thiệu mã không tinh khiết, nó không phải là mặc định. Và ngôn ngữ đi đến độ dài đáng kể để ngăn cản nó. Tuy nhiên, mã không tinh khiết đôi khi hữu ích. Đặc biệt là khi ẩn an toàn sau một giao diện thuần túy. –
Xem thêm http://stackoverflow.com/questions/1916692/are-side-effects-possible-in-pure-functional-programming và http://stackoverflow.com/questions/1916692/are-side-effects-possible -rong-thuần-chức năng-lập trình và http://stackoverflow.com/questions/2488646/why-are-side-effects-modeled-as-monads-in-haskell –