Алгебраические типы данных Haskell - PullRequest
0 голосов
/ 11 марта 2012

У меня есть следующее для тега HTML шрифта:

data Color = HexColor Int | RGBColor Int Int Int | ColorString String deriving Show
data FontAttribute = Size Int | Face String | FontColor Color deriving Show
data Font = Font [FontAttribute] deriving Show

Я строю один так:

Font [Size 23,Face "Arial",Color (RGBColor 240 23 43)]

Меня беспокоит то, что для конструктора данных / значений FontColor с типом FontAttribute в качестве аргумента требуется тип Color. Это означает, что Color является атрибутом универсального типа для любого типа тега, а конкретный тег имеет определенное подмножество атрибутов (в этом случае Font имеет FontAttribute, который может быть Size, Face или FontColor). Есть ли более ясный способ выразить это или моя реализация звучит?

1 Ответ

1 голос
/ 12 марта 2012

Цвет - это просто тип, а не атрибут. В системе типов нет ничего, что указывало бы на то, что Color имеет какие-либо особые отношения с FontAttribute. Все, что происходит, когда вы определяете тип данных FontAttribute, это то, что он создает конструктор с именем FontColor, который представляет собой обычную функцию со следующей сигнатурой типа:

FontColor :: Color -> FontAttribute

Итак, если вы объявили какой-то новый тип с именем Link:

data LinkAttrubute = LinkColor Color | ...

Тогда цвет также может быть сохранен в атрибуте LinkAttribute. Конструктор не подразумевает исключительную связь только с этим типом данных. Весь ваш тип данных FontAttribute говорит о том, что он МОЖЕТ содержать только цвет.

Haskell не имеет встроенной концепции атрибутов, поскольку он не имеет встроенной концепции объектов. ОДНАКО, вы можете моделировать атрибуты, используя тип Lens из пакета data-lens (или fclabels). Я бы связал вам пакеты, но я нахожусь на моем телефоне, и это сложно.

...