Добавление производных (данных) к стандартным типам
Вопрос
Я хотел бы добавить deriving (Data)
к стандартным типам.После включения StandaloneDeriving
, FlexibleContexts
, DeriveDataTypeable
, и UndecidableInstances
расширения, ghc принимает
deriving instance Data Day => Data (Day)
Однако, если я сделаю то же самое для DiffTime
Я получаю
TemperatureRecord.hs:30:0: The data constructors of `DiffTime' are not all in scope so you cannot derive an instance for it In the stand-alone deriving instance for `(Data DiffTime) => Data (DiffTime)'
Я делаю все это, чтобы помочь автоматически генерировать двоичные экземпляры стандартных типов.Итак, у меня есть два вопроса:
- Как мне устранить ошибку, с которой я сталкиваюсь
DiffTime
, и - Каков правильный способ сделать стандартные библиотечные типы двоичными сериализуемыми в Haskell?
Решение
В time
упаковка не раскрывает MkDiffTime
, DiffTime
конструктор.
Чтобы создать Data
например, вы обычно работаете с конструкторами типа.Даже если вы автоматически выводите его, это то, что производный экземпляр также будет делать.
К счастью, это можно было в какой-тостепени обойти.Вы можете извлечь данные из DiffTime
используя toRational
, и вы можете обернуть число в DiffTime
используя fromRational
.Таким образом, должна быть возможность "подделать" Data
экземпляр с "поддельным" конструктором.Это было бы сделано "вручную" (без вывода).
Относительно того, почему конструктор DiffTime
не раскрывается - это было бы похоже на рассуждения, лежащие в основе private
в C ++ и др.Это дает создателям DiffTime
свобода изменять его реализацию, ничего не нарушая.Действительно, если они изменят структуру, это не сломает вашу "подделку". Data
экземпляр и не нарушит ваш формат сериализации.
Другие советы
Я новичок в haskell, но я думаю, вы можете сделать это, чтобы предоставить конструктор (и, следовательно, автоматически выводимые данные)
время распаковки кабалы
изменение
newtype DiffTime = вывод Пико MkDiffTime (эквалайзер, Порядок
Для
DiffTime данных = MkDiffTime получения Пико (эквалайзер, порядок
и установка cabal, похоже, работает