Как организовать модули Haskell с экземплярами: придерживаться типа данных против класса типа? - PullRequest
13 голосов
/ 10 июля 2011

Общий вопрос: какая структура модуля более удобна при добавлении экземпляров для существующих объектов?Какие плюсы и минусы есть?

Допустим, я хочу добавить экземпляр NFData для типа Seq.Я могу поместить его в:

  • Data.Sequence.Extra (как и в пакете vty )
  • Data.Sequence.Instances.NFData (точнее)
  • Control.DeepSeq.Instances
  • Control.DeepSeq.Instances.Sequence

Это тот случай, когда я не владею ни классом типа, ни типом данных.Другая распространенная ситуация - когда я владею классом типа типа и хочу добавить экземпляры для типов данных из некоторого «тяжелого» пакета из Hackage, такого как OpenGL.Скажем, класс типов, который я разработал, очень легкий и не имеет прямого отношения к OpenGL.Я не хочу, чтобы мой класс типов зависел от «тяжелого» пакета, поэтому я хочу поместить экземпляры OpenGL в отдельный модуль (это мое интуитивное чувство, если у вас есть другое мнение, давайте обсудим это).Итак, каким должен быть этот модуль:

  • MyClass.Instances.OpenGL
  • Graphics.Rendering.OpenGL.Extra (вместе с экземплярами для других классов)
  • Graphics.Rendering.OpenGL.Instances.MyClass

Что является более гибким решением?В какой-то момент OpenGL может быть заменен другой библиотекой или MyClass также может быть заменен.Есть ли тонкие нюансы?

Кроме того, какая схема лучше, если выбрать MyClass.Instances вариант:

  • MyClass.Class модуль для самого класса и базовых экземпляров и MyClass модульреэкспортирует его (и, возможно, MyClass.Instances)
  • MyClass модуль для класса и базовых экземпляров, и MyClass.All реэкспортирует все
  • MyClass модуль для класса и базовых экземпляров, и нетмодуль для реэкспорта.

1 Ответ

12 голосов
/ 10 июля 2011

Обычный процесс принятия решения, куда поместить экземпляр, выглядит примерно так:

  1. Если вы создаете новый тип данных и хотите создать экземпляр для существующего класса:

    Поместите экземпляр в тот же модуль, что и тип данных.

  2. Если вы создаете новый класс типов и хотите создавать экземпляры для существующих типов.

    Поместите экземпляры в тот же модуль, что и класс типов.

  3. И класс типа, и тип данных уже существуют (ваш случай).

    Если экземпляр достаточно общий, я бы связался с автором либо класса типа, либо типа данных и попытался бы убедить их добавить экземпляр в свой пакет.

    В противном случае создайте оболочку newtype и напишите для нее экземпляр.

    Только в крайнем случае рассмотрите создание экземпляра для сироты.

...