2011-12-25 23 views
10

tôi đã nhận thấy thành ngữ này trong Data.Unique:Làm thế nào an toàn là 'unsafePerformIO (newTVarIO 0) `?

uniqSource :: TVar Integer 
uniqSource = unsafePerformIO (newTVarIO 0) 
{-# NOINLINE uniqSource #-} 

Có đảm bảo chỉ chạy một lần?

+0

Theo nguyên tắc chung, 'unsafePerformIO' chỉ nên được sử dụng làm chi tiết triển khai mã thư viện, và sau đó bạn chỉ nên sử dụng nó vì bạn khá chắc chắn rằng hoàn toàn không có cách nào khác để đạt được cùng một hiệu suất/hành vi. Tôi không hoàn toàn chắc chắn tại sao tôi cảm thấy cần phải nói rằng ở đây, vì nó không phải là 100% germane cho câu hỏi, nhưng có bạn đi. –

+0

Liên quan: http://stackoverflow.com/questions/6076129/ – fuz

Trả lời

11

Trong GHC, có. Xem the documentation để biết thêm thông tin; có một biến thể unsafeDupablePerformIO có thể được thực hiện nhiều lần để tránh chi phí dành riêng để đạt được bảo đảm này.

Lưu ý rằng unsafePerformIO để tạo các biến có thể thay đổi không an toàn nói chung; như được mô tả trong tài liệu, bạn có thể tạo một tham chiếu đa hình và sử dụng nó để thực hiện unsafeCoerce. Tuy nhiên, đó không phải là điều bạn có thể làm một cách vô tình và nó không áp dụng cho mã được đề cập (vì loại tham chiếu được chỉ định rõ ràng).

Gói safe-globals tóm tắt "thành ngữ" này (trong khi hữu ích trong một số trường hợp, đó là generally considered an antipattern và không được sử dụng trong mã thông thường) theo cách đảm bảo an toàn.

Xem thêm previous answer trên unsafePerformIO và cảnh báo phải được sử dụng khi áp dụng.

Tôi chắc chắn nó cũng áp dụng cho tất cả các triển khai khác; sự chăm sóc đặc biệt mà GHC thực hiện để tránh việc thực hiện lặp lại chỉ cần thiết trong một cài đặt luồng và tôi không biết về bất kỳ triển khai luồng nào khác của Haskell. GHC là những người thực hiện duy nhất thực sự sử dụng những ngày này, mặc dù ...

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