Записи Haskell, более чистый подход?
Я читал о некоторых проблемах с записями Haskell, в частности, о том, что два элемента в одном модуле не могут иметь одинаковое имя.
Я понимаю, что вы можете обойти это, имея отдельные модули, но я не хотел этого делать и вместо этого пытался использовать этот подход:
class HasX a where
x :: a -> X
data D1 = D1 { d1_x :: X, ... }
instance HasX D1 where
x = d1_x
data D2 = D2 { d2_x :: X, ... }
instance HasX D2 where
x = d2_x
(Это только делает, а не устанавливает, я, конечно, должен написать больше кода для выполнения наборов).
Однако, кажется, объявления класса и экземпляра для всего этого кажутся похожими на шаблонный, который должен быть устранен, используя шаблон haskell или что-то еще.
Есть ли библиотека или расширение для GHC, что делает такой подход менее беспорядочным для записи?
Ответы
Ответ 1
Кажется, Data.Has инкапсулирует много того, что вы ищете. В своем словаре они считают, что их класс типа Knows
ближе к вашему Has
, а также обеспечивает подпись для инъекций.
Они также используют механизм маркировки для рассмотрения проблемы, о которой, как я думаю, вы еще не подумали: записи, содержащие поля, имеющие один и тот же тип. Они используют метки уровня типа для устранения этой неоднозначности.
Для удобства также существует некоторая поддержка, предоставляющая генератор экземпляра Has
с шаблоном Haskell в Has-TH
Вы можете найти больше ярлыков типа и других материалов, относящихся к записи, в работах Олега Типа, например OOHaskell (также с Ральфом Леммелем).
Ответ 2
data-accessor-template может по крайней мере помогать писать приемники set/get. Возможно, некоторые люди могут придумать код шаблона Haskell для генерации классов и экземпляров для каждого имени поля записи.
Однако я сам не использую материал Template Haskell. Он ограничивает вас GHC и даже конкретными версиями GHC, поскольку Template Haskell меняет разные версии GHC. Наличие одной (основной) записи для каждого модуля действительно окупается.