Spec-Zone.ru › Haskell 7

System.IO.Unsafe

Авторские права (c) Университет Глазго 2001
Лицензия BSD (см. файл libraries/base/LICENSE)
Поддерживающий libraries@haskell.org
Стабильность временная
Переносимость переносимая
Безопасный Haskell Небезопасный
Язык Haskell2010

Содержание

  • Небезопасные IO операции

Описание

«Небезопасные» операции ввода-вывода.

Небезопасные IO операции

unsafePerformIO :: IO a -> a Исходный код

Это «задний ход» в IO монаде, позволяющий выполнять IO вычисления в любое время. Для обеспечения безопасности IO вычисление должно быть свободно от побочных эффектов и независимо от своей среды.

Если вычисление ввода-вывода, заключенное в unsafePerformIO, выполняет побочные эффекты, то относительный порядок этих побочных эффектов (по отношению к главному потоку ввода-вывода или другим вызовам unsafePerformIO) не определен. Кроме того, при использовании unsafePerformIO для создания побочных эффектов, следует принять следующие меры предосторожности, чтобы гарантировать, что побочные эффекты выполняются столько раз, сколько ожидается. Обратите внимание, что эти меры предосторожности необходимы для GHC, но могут быть недостаточными, и другие компиляторы могут потребовать различных мер предосторожности:

  • Используйте {-# NOINLINE foo #-} как директиву для любой функции foo, которая вызывает unsafePerformIO. Если вызов встраивается, ввод-вывод может выполняться более одного раза.
  • Используйте флаг компилятора -fno-cse для предотвращения устранения общих подвыражений в модуле, которое может объединить два побочных эффекта, которые должны были быть отдельными. Хорошим примером является использование нескольких глобальных переменных (например, test в примере ниже).
  • Убедитесь, что вы либо выключили плавание let (-fno-full-laziness), либо что вызов unsafePerformIO не может выходить за пределы лямбды. Например, если вы скажете: f x = unsafePerformIO (newIORef []) , вы можете получить только одну общую ячейку для всех вызовов f. Лучше было бы f x = unsafePerformIO (newIORef [x]) , так как теперь он не может выходить за пределы лямбды.

Менее известно, что unsafePerformIO не является безопасным с точки зрения типов. Например:

    test :: IORef [a]
    test = unsafePerformIO $ newIORef []

    main = do
            writeIORef test [42]
            bang <- readIORef test
            print (bang :: [Char])

Эта программа вызовет ошибку ядра. Эта проблема с полиморфными ссылками хорошо известна в сообществе ML и не возникает при обычном монадическом использовании ссылок. Нет простого способа сделать это невозможным после использования unsafePerformIO. Действительно, можно написать coerce :: a -> b с помощью unsafePerformIO. Поэтому будьте осторожны!

unsafeDupablePerformIO :: IO a -> a Исходный код

Эта версия unsafePerformIO более эффективна, потому что она опускает проверку, что ввод-вывод выполняется только одним потоком. Следовательно, при использовании unsafeDupablePerformIO, существует вероятность, что действие ввода-вывода может быть выполнено несколько раз (на многопроцессорной системе), и поэтому вы должны убедиться, что оно дает одинаковые результаты каждый раз. Может даже случиться, что одно из дублированных действий ввода-вывода выполняется только частично, а затем прерывается в середине без повышения исключения. Следовательно, функции, такие как bracket, нельзя безопасно использовать в unsafeDupablePerformIO.

С версии: 4.4.0.0

unsafeInterleaveIO :: IO a -> IO a Исходный код

unsafeInterleaveIO позволяет IO вычислению откладываться лениво. При передаче значения типа IO a, IO будет выполнено только тогда, когда потребуется значение a. Это используется для реализации ленивого чтения файлов, см. hGetContents.

unsafeFixIO :: (a -> IO a) -> IO a Исходный код

Несколько более быстрая версия fixIO, которая может быть небезопасной для использования с несколькими потоками. Небезопасность возникает при использовании таким образом:

 unsafeFixIO $ \r -> do
    forkIO (print r)
    return (...)

В этом случае дочерний поток получит исключение NonTermination, а не будет ждать значения r для вычисления.

С версии: 4.5.0.0

© The University of Glasgow and others
Licensed under a BSD-style license (see top of the page).
https://downloads.haskell.org/~ghc/7.10.3/docs/html/libraries/base-4.8.2.0/System-IO-Unsafe.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API