Spec-Zone.ru › Haskell 9

GHC.IO

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

Описание

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

API данного модуля нестабилен и не предназначен для использования широкой публикой. Если вам абсолютно необходимо от него зависеть, убедитесь, что вы используете жёсткий верхний предел, например, base < 4.X, а не base < 5, поскольку интерфейс может быстро изменяться без предупреждения.

newtype IO a Источник

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

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

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

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

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

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

С версии: base-4.9.0.0

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

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

Методы

empty :: IO a Источник

(<|>) :: IO a -> IO a -> IO a Источник

some :: IO a -> IO [a] Источник

many :: IO a -> IO [a] Источник

Applicative IO Источник

С версии: base-2.1

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

Определено в GHC.Internal.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 Источник

Functor IO Источник

С версии: base-2.1

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

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

Методы

fmap :: (a -> b) -> IO a -> IO b Источник

(<$) :: a -> IO b -> IO a Источник

Monad IO Источник

С версии: base-2.1

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

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

Методы

(>>=) :: IO a -> (a -> IO b) -> IO b Источник

(>>) :: IO a -> IO b -> IO b Источник

return :: a -> IO a Источник

MonadPlus IO Источник

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

С версии: base-4.9.0.0

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

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

Методы

mzero :: IO a Источник

mplus :: IO a -> IO a -> IO a Источник

MonadFail IO Источник

С версии: base-4.9.0.0

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

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

Методы

fail :: String -> IO a Источник

MonadFix IO Источник

С версии: base-2.1

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

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

Методы

mfix :: (a -> IO a) -> IO a Источник

MonadIO IO Source

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

Детали экземпляра

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

Методы

liftIO :: IO a -> IO a Source

GHCiSandboxIO IO Source

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

Детали экземпляра

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

Методы

ghciStepIO :: IO a -> IO a Source

Quasi IO Source
Instance details

Defined in GHC.Internal.TH.Syntax

Краткое описание методов

qNewName :: String -> IO Name Source

qReport :: Bool -> String -> IO () Source

qRecover :: IO a -> IO a -> IO a Source

qLookupName :: Bool -> String -> IO (Maybe Name) Source

qReify :: Name -> IO Info Source

qReifyFixity :: Name -> IO (Maybe Fixity) Source

qReifyType :: Name -> IO Type Source

qReifyInstances :: Name -> [Type] -> IO [Dec] Source

qReifyRoles :: Name -> IO [Role] Source

qReifyAnnotations :: Data a => AnnLookup -> IO [a] Source

qReifyModule :: Module -> IO ModuleInfo Source

qReifyConStrictness :: Name -> IO [DecidedStrictness] Source

qLocation :: IO Loc Source

qRunIO :: IO a -> IO a Source

qGetPackageRoot :: IO FilePath Source

qAddDependentFile :: FilePath -> IO () Source

qAddTempFile :: String -> IO FilePath Source

qAddTopDecls :: [Dec] -> IO () Source

qAddForeignFilePath :: ForeignSrcLang -> String -> IO () Source

qAddModFinalizer :: Q () -> IO () Source

qAddCorePlugin :: String -> IO () Source

qGetQ :: Typeable a => IO (Maybe a) Source

qPutQ :: Typeable a => a -> IO () Source

qIsExtEnabled :: Расширение -> IO Булево Исходный код

qExtsEnabled :: IO [Расширение] Исходный код

qPutDoc :: DocLoc -> Строка -> IO () Исходный код

qGetDoc :: DocLoc -> IO (Возможность Строки) Исходный код

Цитата IO Исходный код
Детали экземпляра

Определено в GHC.Internal.TH.Syntax

Методы

newName :: Строка -> IO Имя Исходный код

a ~ () => HPrintfType (IO a) Исходный код

С версии: base-4.7.0.0

Детали экземпляра

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

Методы

hspr :: Дескриптор файла -> Строка -> [UPrintf] -> IO a

a ~ () => PrintfType (IO a) Исходный код

С версии: base-4.7.0.0

Детали экземпляра

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

Методы

spr :: Строка -> [UPrintf] -> IO a

Моноид a => Моноид (IO a) Исходный код

С версии: base-4.9.0.0

Детали экземпляра

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

Методы

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

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

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

Полугруппа a => Полугруппа (IO a) Исходный код

С версии: base-4.10.0.0

Детали экземпляра

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

Методы

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

sconcat :: Непустой список (IO a) -> IO a Исходный код

stimes :: Целочисленный b => b -> IO a -> IO a Исходный код

unIO :: IO a -> Состояние RealWorld -> (# Состояние RealWorld, a #) Исходный код

liftIO :: IO a -> Состояние RealWorld -> STret RealWorld a Исходный код

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

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

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

Если вычисление I/O, заключённое в unsafePerformIO, имеет побочные эффекты, то относительный порядок этих побочных эффектов (по отношению к основному стволу I/O или другим вызовам 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. Поэтому будьте осторожны!

ПРЕДУПРЕЖДЕНИЕ: Если вы ищете «способ получить String из „IO String“, то unsafePerformIO не подходит. Ознакомьтесь с синтаксисом `do-notation` и элементом <- перед продолжением.

unsafeInterleaveIO :: IO a -> IO a Source

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

unsafeDupablePerformIO :: IO a -> a Source

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

С версии: base-4.4.0.0

unsafeDupableInterleaveIO :: IO a -> IO a Source

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

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

noDuplicate :: IO () Source

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

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

stToIO :: ST RealWorld a -> IO a Source

Встраивание строгого потока состояния в действие 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. (HasExceptionContext, Exception e) => e -> IO a) -> IO a Source

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

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

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

throwIO :: (HasCallStack, Exception e) => e -> IO a Source

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

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

throw e   `seq` ()  ===> throw e
throwIO e `seq` ()  ===> ()

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

Следует предпочесть вариант throwIO вместо throw для возбуждения исключения в рамках монады IO, так как он гарантирует порядок выполнения по отношению к другим операциям, в то время как throw этого не делает. Мы говорим, что throwIO возбуждает *точные* исключения, а throw, error и т.д. — *неточные* исключения. Например

throw e + error "boom" ===> error "boom"
throw e + error "boom" ===> throw e

оба являются допустимыми вычислениями, и компилятор может выбрать любой (цикл, даже), в то время как

throwIO e >> error "boom" ===> throwIO e

всегда возбудит исключение e при выполнении.

См. также страницу вики-справочника GHC по точным исключениям для более технического введения в то, как GHC оптимизирует работу с точными и неточными исключениями.

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: асинхронные исключения замаскированы, и операции блокирования не могут быть прерваны

Примеры реализации
Подробности примеров реализации
Show MaskingState Исходный код

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

Подробности реализации

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

Методы

showsPrec :: Int -> MaskingState -> ShowS Исходный код

show :: MaskingState -> String Исходный код

showList :: [MaskingState] -> ShowS Исходный код

Eq MaskingState Исходный код

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

Подробности реализации

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

Методы

(==) :: MaskingState -> MaskingState -> Bool Исходный код

(/=) :: MaskingState -> MaskingState -> Bool Исходный код

getMaskingState :: IO MaskingState Исходный код

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

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

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

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

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

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

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

bracket Исходный код

Аргументы

:: IO a

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

-> (a -> IO b)

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

-> (a -> IO c)

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

-> IO c

finally Исходный код

Аргументы

:: IO a

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

-> IO b

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

-> IO a

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

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

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

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

evaluate $ force x

Существует тонкое различие между evaluate x и return $! 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 Исходный код

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

Spec-Zone.ru

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