Насколько маленьким я должен делать make-модули в Haskell? - PullRequest
6 голосов
/ 23 октября 2010

Я пишу игру со змеями на Хаскеле.Вот некоторые из вещей, которые у меня есть:

  • A Coord тип данных
  • A Line тип данных
  • A Rect тип данных
  • Класс Polygon класса, который позволяет мне получить Rect в виде серии строк ([Line]).
  • Класс Impassable типа, который позволяет мне получить Line как серия координат ([Coord]), чтобы я мог обнаруживать столкновения между другими Impassable s.
  • A Draw классом для всего, что я хочу нарисовать на экране (HSCurses).
  • Наконец, я использую QuickCheck, поэтому я хочу объявить Arbitrary экземпляры для многих из этих вещей.

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

Я особенно запутался в Arbitrary экземплярах.При использовании -Wall я получаю предупреждения об осиротевших экземплярах, когда я, но эти экземпляры вместе в одном тестовом файле, я понимаю, что могу избежать этого предупреждения, поместив эти экземпляры в тот же модуль, в котором определен тип данных, но затем яВам понадобится import Test.QuickCheck для всех тех модулей, которые кажутся глупыми, потому что QuickCheck требуется только при создании исполняемого файла теста.

Буду признателен за любые советы по конкретной проблеме с QuickCheck, а также по более общей проблеме.как / где программы должны быть разделены на модули.

Ответы [ 4 ]

4 голосов
/ 23 октября 2010

Ты можешь взять свой пирог и съесть его тоже. Вы можете реэкспортировать модули.

module Geometry 
    ( module Coord, module Line, module Rect, module Polygon, module Impassable )
where

Обычно я использую модуль всякий раз, когда у меня есть полная абстракция, т.е. когда значение типа данных отличается от его реализации. Зная немного о вашем коде, я бы, вероятно, сгруппировал Polygon и Impassable вместе, возможно, создав тип данных Collision, чтобы представить, что они возвращают. Но Coord, Line и Rect кажутся хорошими абстракциями и, вероятно, заслуживают своих собственных модулей.

2 голосов
/ 23 октября 2010

В целях тестирования я использую отдельные модули для экземпляров Arbitrary.Несмотря на то, что я обычно избегаю экземпляров-сирот, эти модули создаются только при сборке исполняемого файла теста, поэтому я не обращаю внимания на сирот или на то, что они не -Wall чистые.Вы также можете использовать -fno-warn-orphans, чтобы отключить только это предупреждение.

1 голос
/ 23 октября 2010

Я обычно уделяю больше внимания интерфейсу модуля, который определяется предоставляемыми им функциями, а не типами данных, которые он предоставляет. Некоторые из ваших типов имеют общий набор функций? Тогда я бы положил их в тот же модуль.

Но моя практика, вероятно, не самая лучшая, поскольку я обычно пишу небольшие программы. Я бы посоветовал взглянуть на код из Hackage , чтобы увидеть, что делают сопровождающие пакеты.

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

0 голосов
/ 24 августа 2013

Одним из решений с помощью QuickCheck является использование препроцессора C для выборочного включения произвольных экземпляров при тестировании.Вы помещаете экземпляры Arbitrary прямо в свои основные модули, но оборачиваете их макросами препроцессора, а затем помещаете флаг «test» в свой файл Cabal.

...