GHC.IO.Handle
| Авторские права | (c) The University of Glasgow 1994-2009 |
|---|---|
| Лицензия | см. libraries/base/LICENSE |
| Сопровождающий | libraries@haskell.org |
| Стабильность | предварительная |
| Переносимость | непереносимый |
| Безопасный Haskell | Safe |
| Язык | Haskell2010 |
Описание
Внешний API для реализации Handle в GHC
В Haskell определены операции чтения и записи символов из файлов и в файлы, представленные значениями типа Handle. Каждое значение этого типа — это дескриптор: запись, используемая средой выполнения Haskell для управления вводом-выводом объектов файловой системы. Дескриптор обладает как минимум следующими свойствами:
- управляет ли он вводом, выводом или и тем и другим;
- является ли он открытым, закрытым или частично закрытым;
- поддерживает ли объект позиционирование;
- отключена ли буферизация или включена построчная либо блочная буферизация;
- буфер (длина которого может быть равна нулю).
У большинства дескрипторов также есть текущая позиция ввода-вывода, указывающая, где будет выполнена следующая операция ввода или вывода. Дескриптор является доступным для чтения, если он управляет только вводом либо вводом и выводом; аналогично, он является доступным для записи, если он управляет только выводом либо вводом и выводом. Дескриптор открыт сразу после создания. После закрытия его нельзя использовать ни для ввода, ни для вывода, хотя реализация не может повторно использовать его память, пока на него остаются ссылки. Дескрипторы входят в классы Show и Eq. Строка, получаемая при выводе дескриптора, зависит от системы; она должна содержать достаточно информации, чтобы идентифицировать дескриптор при отладке. Согласно == дескриптор равен только самому себе; сравнение внутреннего состояния разных дескрипторов на равенство не выполняется.
data BufferMode Источник
Поддерживаются три вида буферизации: построчная, блочная и без буферизации. Эти режимы оказывают следующее влияние. При выводе данные записываются из внутреннего буфера или сбрасываются согласно режиму буферизации:
-
построчная буферизация: весь буфер вывода сбрасывается при выводе символа новой строки, переполнении буфера, выполнении
hFlushили закрытии дескриптора. -
блочная буферизация: весь буфер записывается при его переполнении, выполнении
hFlushили закрытии дескриптора. - без буферизации: данные выводятся немедленно и никогда не сохраняются в буфере.
Реализация может сбрасывать буфер чаще, но не реже, чем указано выше. Буфер вывода очищается сразу после записи его содержимого.
Аналогичным образом, ввод выполняется в соответствии с режимом буферизации дескриптора:
- построчная буферизация: если буфер дескриптора не пуст, следующий элемент берётся из буфера; если же буфер пуст, в него считываются символы вплоть до следующего символа новой строки включительно. Символы недоступны, пока не будет получен символ новой строки или буфер не заполнится.
- блочная буферизация: когда буфер дескриптора становится пустым, в него считывается следующий блок данных.
-
без буферизации: считывается и возвращается следующий элемент ввода. Операция
hLookAheadподразумевает, что даже дескриптор без буферизации может потребовать буфер размером в один символ.
Режим буферизации по умолчанию при открытии дескриптора зависит от реализации и может зависеть от объекта файловой системы, связанного с этим дескриптором. В большинстве реализаций обычные файлы, как правило, используют блочную буферизацию, а терминалы — построчную.
Конструкторы
| NoBuffering | буферизация отключается, если это возможно. |
| LineBuffering | построчная буферизация включается, если это возможно. |
| BlockBuffering (Maybe Int) | блочная буферизация включается, если это возможно. Размер буфера составляет |
Экземпляры
Аргументы
| :: (RawIO dev, IODevice dev, BufferedIO dev, Typeable dev) | |
| => dev | базовое устройство ввода-вывода, которое должно поддерживать |
| -> FilePath | строка с описанием |
| -> IOMode | |
| -> Maybe TextEncoding | |
| -> NewlineMode | |
| -> IO Handle |
создаёт новый Handle
mkDuplexHandle :: (RawIO dev, IODevice dev, BufferedIO dev, Typeable dev) => dev -> FilePath -> Maybe TextEncoding -> NewlineMode -> IO Handle Источник
аналогично mkFileHandle, но создаётся Handle с двумя независимыми буферами: одним для чтения и другим для записи. Используется для полнодуплексных потоков, например сетевых сокетов.
hFileSize :: Handle -> IO Integer Источник
Для дескриптора hdl, связанного с физическим файлом, hFileSize hdl возвращает размер этого файла в 8-битных байтах.
hSetFileSize :: Handle -> Integer -> IO () Источник
hSetFileSize hdl size усекает физический файл, связанный с дескриптором hdl, до size байт.
hIsEOF :: Handle -> IO Bool Источник
Для доступного для чтения дескриптора hdl, hIsEOF hdl возвращает True, если из hdl больше нельзя получить данные или, в случае физического файла, если текущая позиция ввода-вывода совпадает с длиной файла. В противном случае возвращается False.
ПРИМЕЧАНИЕ: hIsEOF может блокироваться, поскольку для определения наличия данных для чтения ей необходимо попытаться прочитать данные из потока.
Вычисление isEOF идентично hIsEOF, но работает только с stdin.
hLookAhead :: Handle -> IO Char Источник
Вычисление hLookAhead возвращает следующий символ из дескриптора, не удаляя его из буфера ввода, и блокируется до тех пор, пока символ не станет доступен.
Эта операция может завершиться ошибкой:
-
isEOFErrorесли достигнут конец файла.
hSetBuffering :: Handle -> BufferMode -> IO () Источник
Вычисление hSetBuffering hdl mode задаёт режим буферизации для дескриптора hdl при последующих операциях чтения и записи.
Если режим буферизации меняется с BlockBuffering или LineBuffering на NoBuffering, то:
- если
hdlдоступен для записи, буфер сбрасывается так же, как приhFlush; - если
hdlнедоступен для записи, содержимое буфера отбрасывается.
Эта операция может завершиться ошибкой:
-
isPermissionErrorесли дескриптор уже использовался для чтения или записи, а реализация не позволяет изменить режим буферизации.
hSetBinaryMode :: Handle -> Bool -> IO () Источник
Выбирает двоичный режим (True) или текстовый режим (False) для открытого дескриптора. (См. также openBinaryFile.)
Это равносильно вызову hSetEncoding с char8 и вызову hSetNewlineMode с noNewlineTranslation.
hSetEncoding :: Handle -> TextEncoding -> IO () Источник
Действие hSetEncoding hdl encoding изменяет текстовую кодировку дескриптора hdl на encoding. Кодировка по умолчанию при создании Handle — localeEncoding, то есть кодировка по умолчанию для текущей локали.
Чтобы создать Handle без какой-либо кодировки, используйте openBinaryFile. Чтобы прекратить дальнейшее кодирование или декодирование для существующего Handle, используйте hSetBinaryMode.
Для смены кодировки hSetEncoding может потребоваться сбросить буферизованные данные.
hGetEncoding :: Handle -> IO (Maybe TextEncoding) Источник
Возвращает текущую TextEncoding указанного Handle или Nothing, если Handle находится в двоичном режиме.
Обратите внимание, что TextEncoding не сохраняет сведения о состоянии кодировщика/декодировщика, используемого для этого Handle. Например, если используется кодировка UTF-16, сохранение и восстановление кодировки с помощью hGetEncoding и hSetEncoding может привести к записи в файл дополнительной метки порядка байтов.
hFlush :: Handle -> IO () Источник
Действие hFlush hdl немедленно передаёт операционной системе все данные, буферизованные для вывода в дескрипторе hdl.
Эта операция может завершиться ошибкой:
-
isFullErrorесли устройство заполнено; -
isPermissionErrorесли будет превышено ограничение системных ресурсов. В таких обстоятельствах не определено, будут ли символы в буфере отброшены или сохранены.
hFlushAll :: Handle -> IO () Источник
Действие hFlushAll hdl сбрасывает все буферизованные данные в hdl, включая буферизованные данные чтения. Буферизованные данные чтения сбрасываются путём возврата позиции файла к точке перед чтением этих данных, поэтому это работает только в том случае, если hdl поддерживает позиционирование (см. hIsSeekable).
Эта операция может завершиться ошибкой:
-
isFullErrorесли устройство заполнено; -
isPermissionErrorесли будет превышено ограничение системных ресурсов. В таких обстоятельствах не определено, будут ли символы в буфере отброшены или сохранены; -
isIllegalOperationеслиhdlсодержит буферизованные данные чтения и не поддерживает позиционирование.
hDuplicate :: Handle -> IO Handle Источник
Возвращает дубликат исходного дескриптора с собственным буфером. Однако оба дескриптора будут совместно использовать указатель файла. Перед дублированием дескриптора буфер исходного дескриптора сбрасывается, включая отбрасывание всех входных данных.
hDuplicateTo :: Handle -> Handle -> IO () Источник
Делает второй дескриптор дубликатом первого. Сначала второй дескриптор будет закрыт, если он ещё не закрыт.
Это можно использовать для перенаправления стандартных дескрипторов, например:
do h <- openFile "mystdout" WriteMode hDuplicateTo h stdout
hClose :: Handle -> IO () Источник
Вычисление hClose hdl закрывает дескриптор hdl. Перед завершением вычисления, если hdl доступен для записи, его буфер сбрасывается, как при hFlush. Выполнение hClose для уже закрытого дескриптора не оказывает никакого эффекта и не считается ошибкой. Все остальные операции с закрытым дескриптором завершатся неудачей. Если hClose завершится неудачей по какой-либо причине, все дальнейшие операции с дескриптором (кроме hClose) всё равно будут завершаться неудачей, как если бы hdl было успешно закрыто.
hClose — это прерываемая операция в смысле, описанном в Control.Exception. Если hClose будет прервано асинхронным исключением во время сброса буферов, устройство ввода-вывода (например, файл) всё равно будет закрыто.
hClose_help :: Handle__ -> IO (Handle__, Maybe SomeException) Источник
Указывает режим блокировки файла.
Конструкторы
| SharedLock | |
| ExclusiveLock |
hLock :: Handle -> LockMode -> IO () Источник
Если Handle ссылается на файловый дескриптор, выполняется попытка заблокировать содержимое соответствующего файла в указанном режиме. Если файл уже заблокирован в несовместимом режиме, эта функция блокируется до получения блокировки. Блокировка автоматически снимается при закрытии Handle.
Следует учитывать следующее:
- Эта функция может заблокироваться внутри вызова C. В этом случае для возможности прервать её асинхронными исключениями и/или обеспечить работу других потоков НЕОБХОДИМО использовать многопоточную версию системы выполнения.
- Реализация использует одну из нескольких возможностей блокировки — в зависимости от поддержки платформы:
-
LockFileExиспользуется в Windows - На платформах, поддерживающих это, используются
F_OFD_SETLKиF_OFD_SETLKWfnctl. - В остальных случаях используется
flock
поэтому здесь также применимы все связанные с ними ограничения.
- На платформах, отличных от Windows, где
flockне поддерживается (например, в Solaris), эта функция выбрасываетFileLockingNotImplemented. Мы намеренно не предоставляем блокировку на основе fcntl, поскольку её семантика нарушена.
Начиная с: base-4.10.0.0
hTryLock :: Handle -> LockMode -> IO Bool Источник
Неблокирующая версия hLock.
Возвращает True, если блокировку удалось получить, и False в противном случае.
Начиная с: base-4.10.0.0
type HandlePosition = Integer Источник
data HandlePosn Источник
Конструкторы
| HandlePosn Handle HandlePosition |
Экземпляры
| Eq HandlePosn Источник | Начиная с: base-4.1.0.0 |
Определён в GHC.Internal.IO.Handle Методы(==) :: HandlePosn -> HandlePosn -> Bool Источник (/=) :: HandlePosn -> HandlePosn -> Bool Источник | |
| Show HandlePosn Источник | Начиная с: base-4.1.0.0 |
Определён в GHC.Internal.IO.Handle МетодыshowsPrec :: Int -> HandlePosn -> ShowS Источник show :: HandlePosn -> String Источник showList :: [HandlePosn] -> ShowS Источник | |
hGetPosn :: Handle -> IO HandlePosn Источник
Вычисление hGetPosn hdl возвращает текущую позицию ввода-вывода дескриптора hdl в виде значения абстрактного типа HandlePosn.
hSetPosn :: HandlePosn -> IO () Источник
Если вызов hGetPosn hdl возвращает позицию p, то вычисление hSetPosn p устанавливает для hdl позицию, которую он занимал во время вызова hGetPosn.
Эта операция может завершиться неудачей в следующих случаях:
-
isPermissionError, если будет превышен лимит системных ресурсов.
Режим, определяющий действие hSeek hdl mode i.
Конструкторы
| AbsoluteSeek | позиция |
| RelativeSeek | позиция |
| SeekFromEnd | позиция |
Экземпляры
hSeek :: Handle -> SeekMode -> Integer -> IO () Источник
Вычисление hSeek hdl mode i устанавливает позицию дескриптора hdl в зависимости от mode. Смещение i задаётся в 8-битных байтах.
Если для hdl используется блочная или построчная буферизация, то при переходе к позиции за пределами текущего буфера сначала все элементы выходного буфера записываются на устройство, а затем входной буфер отбрасывается. Некоторые дескрипторы не поддерживают позиционирование (см. hIsSeekable) или поддерживают лишь часть возможных операций позиционирования (например, может быть возможен переход только в конец ленты либо на положительное смещение от начала или текущей позиции). Нельзя задать отрицательную позицию ввода-вывода или, для физического файла, позицию за пределами текущего конца файла.
Эта операция может завершиться неудачей в следующих случаях:
-
isIllegalOperationError, если дескриптор не поддерживает позиционирование или не поддерживает запрошенный режим позиционирования. -
isPermissionError, если будет превышен лимит системных ресурсов.
hTell :: Handle -> IO Integer Источник
Вычисление hTell hdl возвращает текущую позицию дескриптора hdl в виде количества байтов от начала файла. Возвращённое значение впоследствии можно передать в hSeek, чтобы переместить дескриптор в текущую позицию.
Эта операция может завершиться ошибкой:
-
isIllegalOperationError, если дескриптор не поддерживает позиционирование.
hIsOpen :: Handle -> IO Bool Источник
hIsOpen hdl возвращает информацию о том, открыт ли дескриптор. Если haType у hdl — ClosedHandle или SemiClosedHandle, возвращается False, в противном случае — True.
hIsClosed :: Handle -> IO Bool Источник
hIsOpen hdl возвращает информацию о том, закрыт ли дескриптор. Если haType у hdl — ClosedHandle, возвращается True, в противном случае — False.
hIsReadable :: Handle -> IO Bool Источник
hIsReadable hdl возвращает информацию о том, можно ли читать из дескриптора.
hIsWritable :: Handle -> IO Bool Источник
hIsWritable hdl возвращает информацию о том, можно ли записывать в дескриптор.
hGetBuffering :: Handle -> IO BufferMode Источник
Вычисление hGetBuffering hdl возвращает текущий режим буферизации для hdl.
hIsSeekable :: Handle -> IO Bool Источник
hIsSeekable hdl возвращает информацию о том, возможно ли hSeek с заданным дескриптором.
hSetEcho :: Handle -> Bool -> IO () Источник
Устанавливает режим эха для дескриптора, связанного с терминалом.
hGetEcho :: Handle -> IO Bool Источник
Получает режим эха для дескриптора, связанного с терминалом.
hIsTerminalDevice :: Handle -> IO Bool Источник
Связан ли дескриптор с терминалом?
В Windows результат hIsTerminalDevide может вводить в заблуждение, поскольку эмуляторы терминала, не являющиеся нативными, например MinTTY, используемый в средах MSYS и Cygwin, реализованы посредством перенаправления. Для их распознавания используйте System.Win32.Types.withHandleToHANDLE System.Win32.MinTTY.isMinTTYHandle. Также рассмотрите пакет ansi-terminal для поддержки терминалов на разных платформах.
hSetNewlineMode :: Handle -> NewlineMode -> IO () Источник
Устанавливает NewlineMode для указанного Handle. Сначала сбрасываются все буферизованные данные.
Представление символа новой строки во внешнем файле или потоке.
Экземпляры
| Eq Newline Источник | Начиная с: base-4.2.0.0 |
| Ord Newline Источник | Начиная с: base-4.3.0.0 |
Определено в GHC.Internal.IO.Handle.Types | |
| Read Newline Источник | Начиная с: base-4.3.0.0 |
| Show Newline Источник | Начиная с: base-4.3.0.0 |
data NewlineMode Источник
Задаёт способ преобразования символов новой строки (если оно выполняется) между внутренними строками и внешним файлом или потоком. Предполагается, что в строках Haskell символы новой строки представлены символом '\n'; режим обработки новых строк задаёт, как преобразовывать '\n' при выводе и во что преобразовывать '\n' при вводе.
Конструкторы
| NewlineMode | |
Экземпляры
nativeNewline :: Newline Источник
Системное представление символа новой строки для текущей платформы: LF в системах Unix, CRLF в Windows.
noNewlineTranslation :: NewlineMode Источник
Не выполнять преобразование символов новой строки.
noNewlineTranslation = NewlineMode { inputNL = LF, outputNL = LF }
universalNewlineMode :: NewlineMode Источник
Преобразует '\r\n' в '\n' при вводе, а '\n' — в системное представление символа новой строки при выводе. Этот режим можно использовать на любой платформе; он работает с текстовыми файлами, использующими любые соглашения о переводе строки. Недостаток в том, что readFile >>= writeFile может привести к созданию другого файла.
universalNewlineMode = NewlineMode { inputNL = CRLF,
outputNL = nativeNewline }
nativeNewlineMode :: NewlineMode Источник
Использует системное представление символа новой строки как при вводе, так и при выводе
nativeNewlineMode = NewlineMode { inputNL = nativeNewline
outputNL = nativeNewline }
hShow :: Handle -> IO String Источник
hShow выполняется в монаде IO и возвращает более подробные сведения, чем (чистый) экземпляр Show для Handle.
hWaitForInput :: Handle -> Int -> IO Bool Источник
Вычисление hWaitForInput hdl t ожидает появления входных данных в дескрипторе hdl. Оно возвращает True, как только входные данные становятся доступными в hdl, или False, если данные не поступили в течение t миллисекунд. Обратите внимание, что hWaitForInput ожидает появления одного или нескольких полных символов, поэтому выполняет декодирование и, следовательно, может завершиться ошибкой декодирования.
Если t меньше нуля, hWaitForInput ожидает бесконечно.
Эта операция может завершиться ошибкой:
-
isEOFErrorесли достигнут конец файла. - ошибка декодирования, если входные данные начинаются с недопустимой последовательности байтов в кодировке этого дескриптора.
ПРИМЕЧАНИЕ для пользователей GHC: если вы не используете флаг -threaded, hWaitForInput hdl t, где t >= 0, будет блокировать все остальные потоки Haskell на время вызова. В этом отношении он ведёт себя как safe внешний вызов.
hGetChar :: Handle -> IO Char Источник
Вычисление hGetChar hdl считывает символ из файла или канала, управляемого hdl, и блокируется до появления символа.
Эта операция может завершиться с ошибкой:
-
isEOFErrorесли достигнут конец файла.
hGetLine :: Handle -> IO String Источник
Вычисление hGetLine hdl считывает строку из файла или канала, управляемого hdl. hGetLine не включает символ новой строки в результат.
Строка отделяется символом новой строки, заданным с помощью hSetNewlineMode, или по умолчанию с помощью nativeNewline. Считанные символы новой строки не включаются в результат.
Если hGetLine встречает конец файла во время чтения в середине строки, он считается концом строки, и возвращается (частичная) строка.
Эта операция может завершиться с ошибкой:
-
isEOFErrorесли конец файла встречен при чтении первого символа строки.
Примеры
>>> withFile "/home/user/foo" ReadMode hGetLine >>= putStrLn this is the first line of the file :O
>>> withFile "/home/user/bar" ReadMode (replicateM 3 . hGetLine) ["this is the first line","this is the second line","this is the third line"]
hGetContents :: Handle -> IO String Источник
Вычисление hGetContents hdl возвращает список символов, соответствующих непрочитанной части канала или файла, управляемого hdl, который переводится в промежуточное состояние — полузакрытое. В этом состоянии hdl фактически закрыт, но элементы считываются из hdl по запросу и накапливаются в специальном списке, возвращаемом hGetContents hdl.
Любая операция, завершающаяся ошибкой из-за закрытого дескриптора, также завершается ошибкой, если дескриптор полузакрыт. Единственное исключение — hClose. Полузакрытый дескриптор становится закрытым:
- если к нему применяется
hClose; - если при чтении элемента из дескриптора возникает ошибка ввода-вывода;
- или после чтения всего содержимого дескриптора.
После того как полузакрытый дескриптор становится закрытым, содержимое связанного с ним списка становится неизменным. Содержимое этого окончательного списка определено лишь частично: он будет содержать как минимум все элементы потока, которые были вычислены до закрытия дескриптора.
Все ошибки ввода-вывода, возникшие, пока дескриптор был полузакрыт, просто отбрасываются.
Эта операция может завершиться с ошибкой:
-
isEOFErrorесли достигнут конец файла.
hGetContents' :: Handle -> IO String Источник
Операция hGetContents' считывает все входные данные из заданного дескриптора, прежде чем вернуть их в виде String и закрыть дескриптор.
Это строгая версия hGetContents
С версии: base-4.15.0.0
hPutChar :: Handle -> Char -> IO () Источник
Вычисление hPutChar hdl ch записывает символ ch в файл или канал, управляемый hdl. Если для hdl включена буферизация, символы могут буферизироваться.
Эта операция может завершиться с ошибкой:
-
isFullErrorесли устройство заполнено. -
isPermissionErrorесли будет превышен другой системный лимит ресурсов.
hPutStr :: Handle -> String -> IO () Источник
Вычисление hPutStr hdl s записывает строку s в файл или канал, управляемый hdl.
Обратите внимание, что hPutStr не является потокобезопасной операцией, если BufferMode у hdl не установлено в LineBuffering или BlockBuffering:
>>> let f = forkIO . hPutStr stdout >>> in do hSetBuffering stdout NoBuffering; f "This is a longer string"; f ":D"; f "Hello Haskell"; pure () This: HDiesl lao lHoansgkeerl lstring
>>> let f = forkIO . hPutStr stdout >>> in do hSetBuffering stdout LineBuffering; f "This is a longer string"; f ":D"; f "Hello Haskell"; pure () This is a longer string:DHello Haskell
Эта операция может завершиться с ошибкой:
-
isFullErrorесли устройство заполнено. -
isPermissionErrorесли будет превышен другой системный лимит ресурсов.
hGetBuf :: Handle -> Ptr a -> Int -> IO Int Источник
hGetBuf hdl buf count считывает данные из дескриптора hdl в буфер buf до достижения EOF или считывания count 8-битных байтов. Возвращается фактическое количество считанных байтов. Оно может быть равно нулю, если EOF достигнут до считывания каких-либо данных (или если count равно нулю).
hGetBuf никогда не вызывает исключение EOF, а вместо этого возвращает значение меньше count.
Если дескриптор является каналом или сокетом и записывающая сторона закрыта, hGetBuf будет вести себя так, как если бы был достигнут EOF.
hGetBuf игнорирует действующие TextEncoding и NewlineMode для Handle и считывает байты напрямую.
hGetBufNonBlocking :: Handle -> Ptr a -> Int -> IO Int Источник
hGetBufNonBlocking hdl buf count считывает данные из дескриптора hdl в буфер buf до достижения EOF, считывания count 8-битных байтов или отсутствия данных, доступных для немедленного чтения.
hGetBufNonBlocking идентична hGetBuf, за исключением того, что она никогда не блокируется в ожидании появления данных, а возвращает только те данные, которые доступны. Чтобы дождаться поступления данных перед вызовом hGetBufNonBlocking, используйте hWaitForInput.
Если дескриптор является каналом или сокетом и записывающая сторона закрыта, hGetBufNonBlocking будет вести себя так, как если бы был достигнут EOF.
hGetBufNonBlocking игнорирует действующие TextEncoding и NewlineMode для Handle и считывает байты напрямую.
ПРИМЕЧАНИЕ: в Windows эта функция работает некорректно; она ведёт себя так же, как hGetBuf.
hPutBuf :: Handle -> Ptr a -> Int -> IO () Источник
hPutBuf hdl buf count записывает count 8-битных байтов из буфера buf в дескриптор hdl. Возвращает ().
hPutBuf игнорирует любую текстовую кодировку, применяемую к Handle, и записывает байты напрямую в базовый файл или устройство.
hPutBuf игнорирует действующие TextEncoding и NewlineMode для Handle и записывает байты напрямую.
Эта операция может завершиться с ошибкой:
-
ResourceVanishedесли дескриптор является каналом или сокетом, а читающая сторона закрыта. (Если это POSIX-система и программа не запросила игнорирование SIGPIPE, вместо этого может быть доставлен SIGPIPE, стандартное действие которого — завершение программы).
hPutBufNonBlocking :: Handle -> Ptr a -> Int -> IO Int Источник
© The University of Glasgow and others
Licensed under a BSD-style license (see top of the page).
https://downloads.haskell.org/~ghc/9.14.1/docs/libraries/base-4.22.0.0-66f8/GHC-IO-Handle.html