Ответ 1
В стандартной библиотеке ShowS
определяется как:
type ShowS = String -> String
Это список различий.
Фокус в том, что строка xs
представляется как ShowS
функцией, которая добавляет ее в любой другой список: (xs ++)
. Это позволяет эффективно конкатенации, избегая проблем вложенной левоассоциативной конкатенации (т.е. ((as ++ bs) ++ cs) ++ ds
). Например:
hello = ("hello" ++)
world = ("world" ++)
-- We can "concatenate" ShowS values simply by composing them:
helloworld = hello . world
-- and turn them into Strings by passing them an empty list:
helloworld' = helloworld ""
Он называется ShowS
, потому что он используется при реализации стандартного класса Show
, чтобы обеспечить эффективный Show
ввод больших, глубоко вложенных структур; а также Show
, вы можете реализовать showsPrec
, который имеет тип:
showsPrec :: (Show a) => Int -> a -> ShowS
Это позволяет обрабатывать приоритет оператора и возвращает значение ShowS
. Стандартные экземпляры реализуют это вместо Show
для эффективности; show a
затем определяется через него как showsPrec 0 a ""
. (Это определение по умолчанию относится к классу Show
, поэтому вы можете просто реализовать showsPrec
для полного экземпляра.)