Spec-Zone.ru › Haskell 8

GHC.IO

Авторские права (c) Университет Глазго 1994-2002
Лицензия см. libraries/base/LICENSE
Поддержка cvs-ghc@haskell.org
Устойчивость внутренняя
Переносимость непереносимая (расширения GHC)
Безопасный Haskell Небезопасный
Язык Haskell2010

Описание

Определения для монады IO и её друзей.

newtype IO a Источник

Значение типа IO a — это вычисление, которое при выполнении выполняет некоторое ввод/вывод, прежде чем вернуть значение типа a.

Существует действительно только один способ "выполнить" действие ввода/вывода: связать его с Main.main в вашей программе. Когда ваша программа выполняется, ввод/вывод будет выполнен. Выполнить ввод/вывод из произвольной функции невозможно, если только эта функция сама не находится в монаде IO и вызывается в какой-то момент, прямо или косвенно, из Main.main.

IO — это монада, поэтому действия IO можно комбинировать, используя либо обозначение do, либо операции >> и >>= из класса Monad.

Конструкторы

IO (State# RealWorld -> (# State# RealWorld, a #))
Экземпляры
Подробности о экземплярах
Monad IO

С версии: base-2.1

Подробности о экземпляре

Определено в GHC.Base

Методы

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

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

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

Functor IO

С версии: base-2.1

Подробности о экземпляре

Определено в GHC.Base

Методы

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

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

MonadFix IO

С версии: base-2.1

Подробности о экземпляре

Определено в Control.Monad.Fix

Методы

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

MonadFail IO

С версии: base-4.9.0.0

Подробности о экземпляре

Определено в Control.Monad.Fail

Методы

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

Applicative IO

С версии: base-2.1

Подробности о экземпляре

Определено в GHC.Base

Методы

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

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

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

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

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

GHCiSandboxIO IO

С версии: base-4.4.0.0

Подробности о экземпляре

Определено в GHC.GHCi

Методы

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

MonadPlus IO

С версии: base-4.9.0.0

Подробности о экземпляре

Определено в GHC.Base

Методы

mzero :: IO a Исходный код

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

Alternative IO

С версии: base-4.9.0.0

Подробности о экземпляре

Определено в GHC.Base

Методы

empty :: IO a Исходный код

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

some :: IO a -> IO [a] Исходный код

many :: IO a -> IO [a] Исходный код

MonadIO IO

С версии: base-4.9.0.0

Подробности о экземпляре

Определено в Control.Monad.IO.Class

Методы

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

Semigroup a => Semigroup (IO a)

С версии: base-4.10.0.0

Подробности экземпляра

Определено в GHC.Base

Методы

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

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

stimes :: Integral b => b -> IO a -> IO a Исходный код

Monoid a => Monoid (IO a)

С момента: base-4.9.0.0

Подробности экземпляра

Определено в GHC.Base

Методы

mempty :: IO a Исходный код

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

mconcat :: [IO a] -> IO a Исходный код

a ~ () => HPrintfType (IO a)

С момента: base-4.7.0.0

Подробности экземпляра

Определено в Text.Printf

Методы

hspr :: Handle -> String -> [UPrintf] -> IO a

a ~ () => PrintfType (IO a)

С момента: base-4.7.0.0

Подробности экземпляра

Определено в Text.Printf

Методы

spr :: String -> [UPrintf] -> IO a

unIO :: IO a -> State# RealWorld -> (# State# RealWorld, a #) Исходный код

liftIO :: IO a -> State# RealWorld -> STret RealWorld a Исходный код

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

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. Поэтому будьте осторожны!

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

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

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

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

С момента: base-4.4.0.0

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

unsafeDupableInterleaveIO позволяет лениво откладывать IO вычисление. При передаче значения типа IO a, IO будет выполнено только при запросе значения a.

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

noDuplicate :: IO () Исходный код

Обеспечивает, что приостановки, оцениваемые текущим потоком, уникальны; то есть текущий поток не оценивает ничего, что также оценивается другим потоком, который также выполнил noDuplicate.

Эта операция используется в определении unsafePerformIO для предотвращения выполнения действия ввода-вывода несколько раз, что обычно нежелательно.

stToIO :: ST RealWorld a -> IO a Исходный код

Встроить строгий поток состояния в действие IO. Параметр RealWorld указывает, что внутреннее состояние, используемое вычислением ST, является специальным, предоставляемым монадой IO, и отличается от состояний, используемых вызовами runST.

ioToST :: IO a -> ST RealWorld a Source

Преобразовать действие IO в действие ST. Тип результата ограничен использованием потока состояния RealWorld, и поэтому результат нельзя передать в runST.

unsafeIOToST :: IO a -> ST s a Source

Преобразование действия IO в действие ST. Это основано на том, что IO и ST имеют одинаковое представление с учётом ограничения на тип параметра потока состояния.

unsafeSTToIO :: ST s a -> IO a Source

Преобразование действия ST в действие IO. Это основано на том, что IO и ST имеют одинаковое представление с учётом ограничения на тип параметра потока состояния.

Пример, демонстрирующий, почему это небезопасно, см. https://mail.haskell.org/pipermail/haskell-cafe/2009-April/060719.html

type FilePath = String Source

Имена файлов и каталогов — значения типа String, точное значение которых зависит от операционной системы. Файлы могут быть открыты, что приводит к получению дескриптора, который затем может быть использован для работы с содержимым файла.

catch Source

Аргументы

:: Exception e
=> IO a

Вычисление для выполнения

-> (e -> IO a)

Обработчик для вызова, если возникает исключение

-> IO a

Это простейшая функция обработки исключений. Она принимает один аргумент, выполняет его, и если возникает исключение, выполняется "обработчик" с значением исключения в качестве аргумента. В противном случае результат возвращается обычно. Например:

  catch (readFile f)
        (\e -> do let err = show (e :: IOException)
                  hPutStr stderr ("Warning: Couldn't open " ++ f ++ ": " ++ err)
                  return "")

Обратите внимание, что нам нужно указать сигнатуру типа для e, иначе программа не пройдёт типизацию, так как тип неоднозначен. Хотя можно перехватывать исключения любого типа, см. раздел "Перехват всех исключений" (в Control.Exception) для объяснения проблем с этим.

Для перехвата исключений в чистых (не IO) выражениях см. функцию evaluate.

Обратите внимание, что из-за неопределённого порядка вычислений Haskell выражение может выбросить одно из нескольких возможных исключений: рассмотрим выражение (error "urk") + (1 `div` 0). Выбрасывает ли выражение ErrorCall "urk" или DivideByZero?

Ответ: "может выбросить любое из них"; выбор не детерминирован. Если вы перехватываете любой тип исключения, то можете перехватить любое из них. Если вы вызываете catch с типом IO Int -> (ArithException -> IO Int) -> IO Int, то обработчик может быть вызван с DivideByZero в качестве аргумента, или исключение ErrorCall "urk" может быть передано выше. Если вы вызовете это снова, вы можете получить обратное поведение. Это нормально, потому что catch — это вычисление в монаде IO.

catchException :: Exception e => IO a -> (e -> IO a) -> IO a Source

Перехват исключения в монаде IO.

Обратите внимание, что эта функция является строгой по отношению к действию. То есть, catchException undefined b == _|_. См. для подробностей.

catchAny :: IO a -> (forall e. Exception e => e -> IO a) -> IO a Source

Перехват исключений любого типа в монаде IO.

Обратите внимание, что эта функция является строгой по отношению к действию. То есть, catchAny undefined b == _|_. См. для подробностей.

throwIO :: Exception e => e -> IO a Source

Вариант throw который может быть использован только внутри монады IO.

Несмотря на то, что throwIO имеет тип, являющийся экземпляром типа throw две функции отличаются в деталях:

throw e   `seq` x  ===> throw e
throwIO e `seq` x  ===> x

Первый пример вызовет исключение e, в то время как второй — нет. Фактически, throwIO вызовет исключение только когда используется внутри монады IO.

Вариант throwIO следует использовать по предпочтению throw для повышения исключения внутри монады IO, так как он гарантирует порядок относительно других операций IO, тогда как throw этого не делает.

mask :: ((forall a. IO a -> IO a) -> IO b) -> IO b Source

Выполняет вычисление IO с замаскированными асинхронными исключениями. То есть, любая нить, которая пытается вызвать исключение в текущей нити с throwTo будет заблокирована до тех пор, пока асинхронные исключения не будут снова размаскированы.

Переданный в mask аргумент — функция, принимающая в качестве аргумента другую функцию, которая может быть использована для восстановления текущего состояния маскировки в контексте вычисления с маской. Например, распространённый способ использования mask — это защита получения ресурса:

mask $ \restore -> do
    x <- acquire
    restore (do_something_with x) `onException` release
    release

Этот код гарантирует, что acquire парно с release, маскируя асинхронные исключения для критических участков. (Вместо написания этого кода лучше использовать bracket, которая абстрагирует общий шаблон).

Обратите внимание, что действие restore , переданное в качестве аргумента mask , не обязательно размаскирует асинхронные исключения, оно только восстанавливает состояние маскировки до состояния внешнего контекста. Таким образом, если асинхронные исключения уже замаскированы, mask не может быть использована для размаскирования исключений. Это позволяет, если вы вызываете функцию библиотеки с замаскированными исключениями, быть уверенным, что вызов библиотеки не сможет снова размаскировать исключения. Если вы пишете код библиотеки и вам нужно использовать асинхронные исключения, единственный способ — создать новую нить; см. forkIOWithUnmask.

Асинхронные исключения всё ещё могут быть получены во время маскирования, если замаскированная нить блокируется определённым образом; см. Control.Exception.

Потоки, созданные forkIO наследуют состояние MaskingState от родителя; то есть, чтобы запустить поток в состоянии MaskedInterruptible, используйте mask_ $ forkIO .... Это особенно полезно, если вам нужно установить обработчик исключений в разветвлённом потоке перед получением любых асинхронных исключений. Чтобы создать новый поток в размаскированном состоянии, используйте forkIOWithUnmask.

mask_ :: IO a -> IO a Source

Как mask, но не передаёт действие restore в аргумент.

uninterruptibleMask :: ((forall a. IO a -> IO a) -> IO b) -> IO b Source

Как и mask, но замаскированное вычисление не прерывается (см. Control.Exception). ЭТО НУЖНО ИСПОЛЬЗОВАТЬ С ОСТОРОЖНОСТЬЮ, потому что если поток, выполняющийся в uninterruptibleMask, блокируется по какой-либо причине, то поток (а возможно и программа, если это главный поток) станет неотзываемым и неуничтожимым. Эта функция должна потребоваться только в том случае, если вам нужно замаскировать исключения вокруг прерывимой операции, и вы можете гарантировать, что прерывимая операция будет заблокирована только на короткое время.

uninterruptibleMask_ :: IO a -> IO a Source

Как и uninterruptibleMask, но не передает restore действие аргументу.

data MaskingState Source

Описывает поведение потока при получении асинхронного исключения.

Конструкторы

Unmasked

асинхронные исключения не маскируются (обычное состояние)

MaskedInterruptible

состояние во время mask: асинхронные исключения маскируются, но блокирующие операции все еще могут быть прерваны

MaskedUninterruptible

состояние во время uninterruptibleMask: асинхронные исключения маскируются, и блокирующие операции не могут быть прерваны

Примеры
Подробности примеров
Eq MaskingState

С версии: base-4.3.0.0

Подробности примера

Определено в GHC.IO

Методы

(==) :: MaskingState -> MaskingState -> Bool Source

(/=) :: MaskingState -> MaskingState -> Bool Source

Show MaskingState

С версии: base-4.3.0.0

Подробности примера

Определено в GHC.IO

Методы

showsPrec :: Int -> MaskingState -> ShowS Source

show :: MaskingState -> String Source

showList :: [MaskingState] -> ShowS Source

getMaskingState :: IO MaskingState Source

Возвращает MaskingState для текущего потока.

unsafeUnmask :: IO a -> IO a Source

interruptible :: IO a -> IO a Source

Разрешает асинхронные исключения, даже внутри mask, делая операцию прерывимой (см. обсуждение «Прерывимые операции» в Exception).

При вызове вне mask или внутри uninterruptibleMask, эта функция не оказывает никакого эффекта.

С версии: base-4.9.0.0

onException :: IO a -> IO b -> IO a Source

bracket Source

Аргументы

:: IO a

вычисление, которое выполняется в первую очередь («получить ресурс»)

-> (a -> IO b)

вычисление, которое выполняется последним («освободить ресурс»)

-> (a -> IO c)

вычисление, которое выполняется между ними

-> IO c

finally Source

Аргументы

:: IO a

вычисление, которое выполняется в первую очередь

-> IO b

вычисление, которое выполняется после (даже если было вызвано исключение)

-> IO a

evaluate :: a -> IO a Source

Вычисляет аргумент до слабой головной нормальной формы.

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

evaluate вычисляется только до слабой головной нормальной формы. Если требуется более глубокое вычисление, функция force из Control.DeepSeq может быть полезной:

evaluate $ force x

Существует тонкое различие между evaluate x и x, аналогичное различию между throwIO и throw. Если ленивое значение x вызывает исключение, return $! x не вернёт IO действие и вместо этого вызовет исключение. evaluate x, с другой стороны, всегда производит IO действие; это действие вызовет исключение при выполнении тогда и только тогда, когда x вызывает исключение при вычислении.

Практическое следствие этого различия заключается в том, что из-за семантики неточных исключений,

(return $! error "foo") >> error "bar"

может вызвать либо "foo", либо "bar", в зависимости от оптимизаций, выполняемых компилятором. С другой стороны,

evaluate (error "foo") >> error "bar"

гарантировано вызовет "foo".

Правило гласит: используйте evaluate для принуждения или обработки исключений в ленивых значениях. Если же вы принуждаете ленивое значение только по соображениям эффективности и не беспокоитесь об исключениях, можно использовать return $! x.

mkUserError :: [Char] -> SomeException Source

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

Spec-Zone.ru

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