Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
MakeevGA-Haskell-a4-shortcode_2014_05_31.doc
Скачиваний:
16
Добавлен:
19.01.2023
Размер:
1.79 Mб
Скачать

Функция show

Функция show используется тогда, когда нужно значение определенного типа превратить в строку, вот ее тип:

show :: Show a => a -> String

Предлагаю вам вместе со мной порадоваться этой логичности языка: функция show умеет показывать (преобразовывать в строку) значения только тех типов, которые относятся к классу Show, то есть умеют преобразовываться в строку. А что – логично:

show 1 → "1"

show True → "True"

show "hello" → "\"hello\""

Классу Show принадлежит большинство простейших типов, и, что еще важнее, производные от них сложные структуры. Например, если система умеет отображать число (а она умеет), то она умеет отображать и список чисел, как и список любых других отображаемых значений – для этого система напечатает открывающую квадратную скобку "[", потом через запятую покажет преобразованные в строку элементы списка, а потом закрывающую скобку "]". То же касается и кортежей:

show [1..3] → "[1,2,3]"

show (3, "hello", [1,2,3]) → "(3,\"hello\",[1,2,3])"

На самом деле, когда вы печатаете выражение в командной строке интерпретатора, он вычисляет его значение, а потом преобразовывает его в строку, чтобы вывести на экран. Именно поэтому, если типом выражения будет нечто странное (например, функция), вы увидите ошибку, связанную с тем, что функции show не удается правильно работать с элементами этого типа:

Prelude> sin

ERROR - Cannot find "show" function for:

*** Expression : sin

*** Of type : Double -> Double

Совсем немного о классах

Давайте вспомним, как у нас появилось понятие класса типов. Мы разбирались, применительно к каким типам должна работать, например, операция (>), и решили, что ограничивать ее каким-то одним типом нельзя, но и работать со всеми возможными типами эта операция, очевидно, не может. Тогда и выяснилось, что работать операция (>) может только над типами, входящими в класс Ord, то есть над типами, допускающими сравнение на больше-меньше. Довольно тавтологично, не так ли?

(>) :: Ord a => a -> a -> Bool

В прошлой главе мы встретили функцию show, которая умеет показывать (преобразовывать в строку) значения тех типов, которые относятся к классу Show, то есть умеют преобразовываться в строку. Давайте посмотрим на сам класс Show:

class Show a where

show :: a -> String

Когда определяется класс, задаются все функции, которые должен реализовывать тип, для того, чтобы иметь право принадлежать этому классу. Классы в Haskell – это что-то вроде интерфейсов, или абстрактных классов во многих развитых объектно-ориентированных языках: они перечисляют операции, но не задают никакой реализации. Последнее, правда, для Haskell не совсем верно, вот посмотрите на полное объявление класса Eq:

class Eq a where

(==), (/=) :: a -> a -> Bool

-- Minimal complete definition: (==) or (/=)

x == y = not (x/=y)

x /= y = not (x==y)

Класс Eq заявляет: все, кто хочет сертифицироваться на принадлежность мне, должен будет предоставить мне одно из двух – или свою операцию равенства, или операцию неравенства. То бишь, если ты какой-нибудь Integer, то расскажи классу Eq о том, как сравнивать два значения своего типа, и получи отметку о полном служебном соответствии.

Записка на полях: кстати, а иккс-иггрек-зеет одинаков со строкой "Зачет внимательным читателям", запомните это – вдруг пригодится?

И что тогда? А тогда операция (==) сможет сравнивать и значения твоего типа Integer. Вот он, полиморфизм в стиле Haskell в действии. Видите аналогию? В терминах ООП можно сказать, что операция (==) работает с типами, у которых есть перекрытая реализация полиморфной функции сравнения.

А что же с классом Show? Если у вас есть какой-нибудь новосозданный тип данных, то функция show с ним работать, конечно, не будет. А вот если вы расскажете, как ваш тип преобразовывать в строку, то получите сертификат о том, что ваш тип теперь принадлежит классу Show, и тогда функция show сможет его показывать. Разобрались в тавтологиях?

Позже, когда будем создавать свои собственные типы, мы увидим конкретные примеры.