Spec-Zone.ru › Haskell 9

Text.Printf

Авторские права (c) Lennart Augustsson and Bart Massey 2013
Лицензия в стиле BSD (см. файл LICENSE в этом дистрибутиве)
Сопровождающий Bart Massey <bart@cs.pdx.edu>
Стабильность предварительная
Переносимость переносимый
Безопасный Haskell Safe
Язык Haskell2010

Содержание

  • Функции вывода
  • Добавление поддержки новых типов
    • Обработка модификаторов, зависящих от типа
    • Стандартные форматтеры
    • Генерация ошибок
  • Внутреннее устройство реализации

Описание

Форматтер, подобный C printf(3). Эта версия была расширена Bart Massey согласно рекомендациям John Meacham и Simon Marlow http://comments.gmane.org/gmane.comp.lang.haskell.libraries/4726 для поддержки расширяемого форматирования новых типов данных. Кроме того, она была расширена для поддержки почти всего синтаксиса C printf(3).

Функции вывода

printf :: PrintfType r => String -> r Источник

Форматирует переменное число аргументов с помощью строки форматирования в стиле C.

>>> printf "%s, %d, %.4f" "hello" 123 pi
hello, 123, 3.1416

Возвращаемое значение — либо String, либо (IO a) (что должно быть (IO ()), но система типов Haskell затрудняет это).

Строка формата состоит из обычных символов и спецификаций преобразования, которые указывают, как отформатировать один из аргументов для printf в выходной строке. Спецификация формата начинается с символа %; этот символ можно экранировать в строке формата с помощью %%. Спецификация формата заканчивается символом формата, который содержит основную информацию о форматировании значения. Остальная часть спецификации преобразования необязательна. В указанном порядке могут следовать символы флагов, спецификатор ширины, спецификатор точности и символы модификаторов, зависящие от типа.

В отличие от C printf(3), форматирование этого printf определяется типом аргумента; форматирование зависит от типа. Типы, форматируемые с помощью printf «из коробки»:

  • типы Integral, включая Char
  • String
  • типы RealFloat

Поддержку printf можно расширить и для других типов: см. ниже.

Спецификация преобразования начинается с символа %, за которым может следовать ноль или более следующих флагов:

-      left adjust (default is right adjust)
+      always use a sign (+ or -) for signed conversions
space  leading space for positive numbers in signed conversions
0      pad with zeros rather than spaces
#      use an \"alternate form\": see below

Если заданы оба флага, - имеет приоритет над 0, а + — над пробелом. Отрицательный спецификатор ширины в преобразовании * считается положительным, но подразумевает флаг выравнивания по левому краю.

«Альтернативная форма» для преобразований беззнаковых чисел с основанием системы счисления работает так же, как в C printf(3):

%o           prefix with a leading 0 if needed
%x           prefix with a leading 0x if nonzero
%X           prefix with a leading 0X if nonzero
%b           prefix with a leading 0b if nonzero
%[eEfFgG]    ensure that the number contains a decimal point

После флагов может указываться ширина поля:

num    field width
*      as num, but taken from argument list

Ширина поля задаёт минимум, а не максимум: при необходимости она будет увеличена, чтобы значение не было искажено.

После ширины поля может указываться точность:

.num   precision
.      same as .0
.*     as num, but taken from argument list

Отрицательная точность считается равной 0. Значение точности зависит от типа преобразования.

Integral    minimum number of digits to show
RealFloat   number of digits after the decimal point
String      maximum number of characters

Для целочисленных типов точность задаётся дополнением нулями. Если для целочисленного поля указаны и точность, и дополнение нулями, дополнение нулями игнорируется.

После точности для целочисленных типов может указываться модификатор ширины; он используется только для задания неявного размера операнда при преобразовании отрицательного операнда в беззнаковый:

hh     Int8
h      Int16
l      Int32
ll     Int64
L      Int64

Спецификация заканчивается символом формата:

c      character               Integral
d      decimal                 Integral
o      octal                   Integral
x      hexadecimal             Integral
X      hexadecimal             Integral
b      binary                  Integral
u      unsigned decimal        Integral
f      floating point          RealFloat
F      floating point          RealFloat
g      general format float    RealFloat
G      general format float    RealFloat
e      exponent format float   RealFloat
E      exponent format float   RealFloat
s      string                  String
v      default format          any type

Спецификатор «%v» предусмотрен для всех встроенных типов и также должен быть предусмотрен в форматтерах пользовательских типов. Он выбирает «наилучшее» представление для заданного типа. Для встроенных типов спецификатор «%v» преобразуется следующим образом:

c      Char
u      other unsigned Integral
d      other signed Integral
g      RealFloat
s      String

Несоответствие типов аргументов строке формата, а также любые другие синтаксические или семантические ошибки в строке формата приводят к возникновению исключения во время выполнения.

Обратите внимание, что форматирование типов RealFloat сейчас несколько отличается от форматирования в C printf(3) и вместо этого соответствует showEFloat, showFFloat и showGFloat (а также их альтернативным вариантам showFFloatAlt и showGFloatAlt). Это сложно исправить: исправленные варианты форматировали бы значения несовместимым с предыдущими версиями способом. В любом случае поведение Haskell в целом разумнее, чем поведение C. Краткое описание некоторых ключевых различий:

  • В Haskell printf никогда не используется точность по умолчанию «6 знаков», предусмотренная в C printf.
  • В Haskell printf спецификатор «точности» задаёт количество цифр после десятичной точки.
  • В Haskell printf экспонента чисел в формате e выводится без лишнего знака плюс и с минимально возможным количеством цифр.
  • В Haskell printf при возможности после десятичной точки выводится ноль.

hPrintf :: HPrintfType r => Handle -> String -> r Источник

Аналог printf, но вывод производится в указанный Handle. Возвращаемый тип ограничен типом (IO a).

Добавление поддержки новых типов

Этот printf можно расширить для форматирования типов, не предусмотренных по умолчанию. Для этого нужно создать экземпляр PrintfArg и предоставить formatArg для данного типа. Можно также предоставить parseFormat для обработки модификаторов, зависящих от типа, но обычно лучше использовать экземпляр по умолчанию.

Например:

instance PrintfArg () where
  formatArg x fmt | fmtChar (vFmt 'U' fmt) == 'U' =
    formatString "()" (fmt { fmtChar = 's', fmtPrecision = Nothing })
  formatArg _ fmt = errorBadFormat $ fmtChar fmt

main :: IO ()
main = printf "[%-3.1U]\n" ()

выводит «[() ]». Обратите внимание на использование formatString для удобной обработки спецификаций форматирования поля.

class PrintfArg a where Источник

Класс типов значений, форматируемых в стиле printf. Метод formatArg принимает значение и дескриптор формата поля и либо завершается с ошибкой из-за некорректного дескриптора, либо возвращает в качестве результата ShowS. Реализация parseFormat по умолчанию не ожидает модификаторов: это обычный случай. Минимальная реализация: formatArg.

Минимальное полное определение

formatArg

Методы

formatArg :: a -> FieldFormatter Источник

Начиная с: base-4.7.0.0

parseFormat :: a -> ModifierParser Источник

Начиная с: base-4.7.0.0

Экземпляры
Сведения об экземплярах
PrintfArg Int16 Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

formatArg :: Int16 -> FieldFormatter Источник

parseFormat :: Int16 -> ModifierParser Источник

PrintfArg Int32 Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

formatArg :: Int32 -> FieldFormatter Источник

parseFormat :: Int32 -> ModifierParser Источник

PrintfArg Int64 Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

formatArg :: Int64 -> FieldFormatter Источник

parseFormat :: Int64 -> ModifierParser Источник

PrintfArg Int8 Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

formatArg :: Int8 -> FieldFormatter Источник

parseFormat :: Int8 -> ModifierParser Источник

PrintfArg Word16 Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

formatArg :: Word16 -> FieldFormatter Источник

parseFormat :: Word16 -> ModifierParser Источник

PrintfArg Word32 Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

formatArg :: Word32 -> FieldFormatter Источник

parseFormat :: Word32 -> ModifierParser Источник

PrintfArg Word64 Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

formatArg :: Word64 -> FieldFormatter Источник

parseFormat :: Word64 -> ModifierParser Источник

PrintfArg Word8 Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

formatArg :: Word8 -> FieldFormatter Источник

parseFormat :: Word8 -> ModifierParser Источник

PrintfArg Integer Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

formatArg :: Integer -> FieldFormatter Источник

parseFormat :: Integer -> ModifierParser Источник

PrintfArg Natural Источник

Начиная с: base-4.8.0.0

Сведения об экземпляре

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

Методы

formatArg :: Natural -> FieldFormatter Источник

parseFormat :: Natural -> ModifierParser Источник

PrintfArg Char Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

formatArg :: Char -> FieldFormatter Источник

parseFormat :: Char -> ModifierParser Источник

PrintfArg Double Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

formatArg :: Double -> FieldFormatter Источник

parseFormat :: Double -> ModifierParser Источник

PrintfArg Float Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

formatArg :: Float -> FieldFormatter Источник

parseFormat :: Float -> ModifierParser Источник

PrintfArg Int Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

formatArg :: Int -> FieldFormatter Источник

parseFormat :: Int -> ModifierParser Источник

PrintfArg Word Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

formatArg :: Word -> FieldFormatter Источник

parseFormat :: Word -> ModifierParser Источник

IsChar c => PrintfArg [c] Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

formatArg :: [c] -> FieldFormatter Источник

parseFormat :: [c] -> ModifierParser Источник

type FieldFormatter = FieldFormat -> ShowS Источник

Тип форматтера поля, специализированного для его аргумента.

Начиная с: base-4.7.0.0

data FieldFormat Источник

Описание форматирования поля для formatArg. Описание работы форматирования полей см. в UNIX printf(3).

Начиная с: base-4.7.0.0

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

FieldFormat

Поля

  • fmtWidth :: Maybe Int

    Общая ширина поля.

  • fmtPrecision :: Maybe Int

    Дополнительный спецификатор ширины поля.

  • fmtAdjust :: Maybe FormatAdjustment

    Способ заполнения или дополнения поля.

  • fmtSign :: Maybe FormatSign

    Следует ли обязательно указывать знак «плюс» для положительных чисел.

  • fmtAlternate :: Bool

    Указывает на «альтернативный формат». Подробности см. в printf(3); они зависят от спецификатора аргумента.

  • fmtModifiers :: String

    Символы, которые в формате располагались непосредственно слева от fmtChar и были приняты parseFormat данного типа. Обычно это пустая строка.

  • fmtChar :: Char

    Символ формата, с которым был вызван printf. formatArg должен завершиться ошибкой, если этот символ не соответствует типу. Обычно для одного типа обрабатывается несколько символов формата.

data FormatAdjustment Источник

Определяет, следует ли выравнивать поле по левому краю или заполнять нулями. Эти варианты взаимоисключающие, причём приоритет имеет LeftAdjust.

Начиная с: base-4.7.0.0

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

LeftAdjust
ZeroPad

data FormatSign Источник

Определяет, как обрабатывать знак числового поля. Эти варианты взаимоисключающие, причём приоритет имеет SignPlus.

Начиная с: base-4.7.0.0

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

SignPlus
SignSpace

vFmt :: Char -> FieldFormat -> FieldFormat Источник

Заменяет символ формата 'v' указанным символом формата по умолчанию в FieldFormat. Вспомогательная функция для типов, реализуемых пользователем, которые должны поддерживать "%v".

Начиная с: base-4.7.0.0

Обработка специфичных для типа модификаторов

Если для типа, предоставленного пользователем, потребуются символы-модификаторы, можно задать ModifierParser для их обработки. Полученные модификаторы появятся в FieldFormat и будут доступны форматтеру для конкретного типа.

type ModifierParser = String -> FormatParse Источник

Тип функции, которая разбирает символы-модификаторы из строки формата.

Начиная с: base-4.7.0.0

data FormatParse Источник

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

Начиная с: base-4.7.0.0

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

FormatParse

Поля

  • fpModifiers :: String

    Найденные модификаторы.

  • fpChar :: Char

    Основной символ формата.

  • fpRest :: String

    Остаток строки формата.

Стандартные форматтеры

Эти форматтеры для стандартных типов предоставлены для удобства написания новых форматтеров для конкретных типов: часто для обработки большей части формата нового типа используют formatString или formatInteger.

formatString :: IsChar a => [a] -> FieldFormatter Источник

Форматтер для значений String.

Начиная с: base-4.7.0.0

formatChar :: Char -> FieldFormatter Источник

Форматтер для значений Char.

Начиная с: base-4.7.0.0

formatInt :: (Integral a, Bounded a) => a -> FieldFormatter Источник

Форматтер для значений Int.

Начиная с: base-4.7.0.0

formatInteger :: Integer -> FieldFormatter Источник

Форматтер для значений Integer.

Начиная с: base-4.7.0.0

formatRealFloat :: RealFloat a => a -> FieldFormatter Источник

Форматтер для значений RealFloat.

Начиная с: base-4.7.0.0

Генерация ошибок

Эти функции используются внутри для генерации различных ошибок и экспортируются для использования в новых форматтерах для конкретных типов.

errorBadFormat :: Char -> a Источник

Вызывает perror, чтобы сообщить о неизвестном символе формата для заданного типа.

Начиная с: base-4.7.0.0

errorShortFormat :: a Источник

Вызывает perror, чтобы сообщить о преждевременном окончании строки формата.

Начиная с: base-4.7.0.0

errorMissingArgument :: a Источник

Вызывает perror, чтобы сообщить об отсутствующем аргументе в списке аргументов.

Начиная с: base-4.7.0.0

errorBadArgument :: a Источник

Вызывает perror, чтобы сообщить об ошибке типа или аналогичной ошибке в заданном аргументе.

Начиная с: base-4.7.0.0

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

Вызывает error, добавляя к строке сообщения префикс, специфичный для printf.

Начиная с: base-4.7.0.0

Внутренние детали реализации

Эти типы необходимы для обработки переменного числа аргументов в printf и hPrintf. Их реализация намеренно не видна из этого модуля. Если попытаться передать аргумент типа, не являющегося экземпляром соответствующего класса, в printf или hPrintf, компилятор сообщит об отсутствии экземпляра PrintfArg. (Все экземпляры PrintfArg являются экземплярами PrintfType.)

class PrintfType t Источник

Класс PrintfType обеспечивает механизм работы с переменным числом аргументов для printf. Его реализация намеренно не видна из этого модуля. Если попытаться передать в printf или hPrintf аргумент типа, не являющегося экземпляром этого класса, компилятор сообщит об отсутствии экземпляра PrintfArg.

Минимальное полное определение

spr

Экземпляры
Сведения об экземплярах
a ~ () => PrintfType (IO a) Источник

Начиная с: base-4.7.0.0

Сведения об экземпляре

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

Методы

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

IsChar c => PrintfType [c] Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

spr :: String -> [UPrintf] -> [c]

(PrintfArg a, PrintfType r) => PrintfType (a -> r) Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

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

class HPrintfType t Источник

Класс HPrintfType обеспечивает механизм работы с переменным числом аргументов для hPrintf. Его реализация намеренно не видна из этого модуля.

Минимальное полное определение

hspr

Экземпляры
Сведения об экземплярах
a ~ () => HPrintfType (IO a) Источник

Начиная с: base-4.7.0.0

Сведения об экземпляре

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

Методы

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

(PrintfArg a, HPrintfType r) => HPrintfType (a -> r) Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

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

Этот класс необходим как обходное решение для совместимости с Haskell98, компенсирующее отсутствие FlexibleInstances.

class IsChar c where Источник

Этот класс, имеющий только один экземпляр, используется как обходное решение, поскольку String как конкретный тип не может быть экземпляром класса типов. IsChar экспортируется для обратной совместимости.

Методы

toChar :: c -> Char Источник

Начиная с: base-4.7.0.0

fromChar :: Char -> c Источник

Начиная с: base-4.7.0.0

Экземпляры
Сведения об экземплярах
IsChar Char Источник

Начиная с: base-2.1

Сведения об экземпляре

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

Методы

toChar :: Char -> Char Источник

fromChar :: Char -> Char Источник

© 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/Text-Printf.html

Spec-Zone.ru

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