2012-04-04 12 views
7

Ostatnio czytałem o unsafePerformIO i chciałbym Cię o coś zapytać. Nie przeszkadza mi fakt, że prawdziwy język powinien być w stanie wchodzić w interakcje ze środowiskiem zewnętrznym, więc unsafePerformIO jest w pewnym stopniu uzasadnione. Jednak, o ile mi wiadomo, nie zdaję sobie sprawy z szybkiej metody sprawdzenia, czy interfejs/biblioteka pozornie czysta (sądząc po typach) jest naprawdę czysta bez sprawdzania kodu w poszukiwaniu połączeń pod numerem unsafePerformIO (dokumentacja mogłaby nie wspomnieć o tym). Wiem, że powinien on być używany tylko wtedy, gdy masz pewność, że gwarancja referencyjna jest gwarantowana, ale mimo to chciałbym o tym wiedzieć.Jak sprawdzić, czy pozornie czysty interfejs Haskell ukrywa niebezpieczne operacje?

+3

"Wiem, że powinno to być używane tylko wtedy, gdy masz pewność, że gwarancja referencyjna jest gwarantowana" dokładnie. W powinno być używane tylko wtedy, gdy operacje wewnętrzne nie mogą przeciekać na zewnątrz w jakikolwiek rozsądny sposób, tj. Gdy nie ma możliwości stwierdzenia, że ​​takie rzeczy występują pod maską. – leftaroundabout

+1

Nawiasem mówiąc, używanie 'unsafePerformIO' do interakcji ze środowiskiem zewnętrznym jest dokładnie tym, czego nie wolno robić *. Wszystkie efekty powinny być wewnętrzne dla twojego kodu - takie rzeczy jak używanie zmiennej zmiennej za kulisami do implementacji memoizacji. – ehird

+0

@ehird: Dzięki za dalsze wyjaśnienie, ale kiedy napisałem "environment", miałem na myśli to w szerszym możliwym znaczeniu, które obejmuje również biblioteki zewnętrzne (nie-haskell). Nie myślałem o interakcji użytkownika. –

Odpowiedz

10

Nie ma mowy bez sprawdzenia kodu źródłowego. Nie jest to jednak zbyt trudne, ponieważ Haddock podaje ładny link bezpośrednio do definicji podświetlonych w skrypcie. Zobacz przykładowe linki "Źródło" po prawej stronie definicji na stronie this page.

Safe Haskell dotyczy tutaj; służy do kompilowania kodu Haskella w sytuacjach, w których chcesz zabronić używania niebezpiecznej funkcjonalności. Jeśli moduł używa modułu niebezpiecznego (takiego jak System.IO.Unsafe) i nie jest oznaczony jako Trustworthy, odziedziczy on swój niebezpieczny status. Jednak moduły korzystające z unsafePerformIO generalnie będą go bezpiecznie używać, a tym samym deklarują się jako Trustworthy.

+0

Dziękuję, więc jest tak, jak myślałem ... kod źródłowy lub nic. Cóż, przynajmniej, choć gwarantowane ponownie przez programistę, Safe Haskell może pomóc w automatycznej identyfikacji niektórych niebezpiecznych modułów. –

5

W przypadku, gdy myślisz, użycie unsafePerformIO jest nieuzasadnione. Przetłumaczono to na documentation for unsafePerformIO: dotyczy to tylko przypadków, w których implementujący może udowodnić, że nie ma możliwości złamania przejrzystości referencyjnej, tj. "Czysto funkcjonalnej" semantyki. Oznacza to, że jeśli ktokolwiek używa unsafePerformIO w taki sposób, że program czysto funkcjonalny może go wykryć (np. Napisać funkcję, której wynik zależy nie tylko od jej argumentów), to jest to niedozwolone użycie.

Jeśli wpadłeś na taki przypadek, najbardziej prawdopodobną możliwością jest znalezienie błędu.

+2

Na pytanie: "Wiem, że powinno to być używane tylko wtedy, gdy masz pewność, że gwarancja referencyjna jest gwarantowana, ale mimo to chciałbym o tym wiedzieć". – ehird

+0

@sakundium: Masz rację, już widziałem stronę z dokumentacją dla 'unsafePerformIO', ale to tylko zasada i nie mogę być pewna, że ​​programista faktycznie ma dowód na referencyjną przezroczystość :) –

Powiązane problemy