Соглашения об именах модулей Haskell
Как мне назвать мои модули Haskell для программы, а не библиотеки, и организовать их в иерархии?
Я делаю лучевой трассировщик под названием Luminosity. Сначала у меня были эти модули:
Vector Colour Intersect Trace Render Parse Export
Каждый модуль был в порядке, но я чувствовал, что это не хватает организации.
Сначала я помещаю каждый модуль под Luminosity
, поэтому, например, Vector
теперь был Luminosity.Vector
(я предполагаю, что это стандартно для программы haskell?).
Тогда я подумал: Vector и Color являются независимыми и могут быть повторно использованы, поэтому они должны быть разделены. Но они слишком малы, чтобы превращаться в библиотеки.
Куда они должны идти? Уже (по взлому) есть Data.Vector
и Data.Colour
, так что я должен положить их туда? Или это вызовет путаницу (даже если я импортирую их вместе с другим моим местным импортом)? Если нет, то оно должно быть Luminosity.Data.Vector
или Data.Luminosity.Vector
? Я почти уверен, что видел оба используемых, хотя, возможно, мне просто пришлось посмотреть проект с использованием нетрадиционной структуры.
У меня также есть простой экспортер изображений TGA (Export
), который может быть независим от Luminosity. Кажется, что правильное местоположение было бы Codec.Image.TGA
, но опять же, должно быть Luminosity
где-то там, и если да, то где?
Было бы неплохо, если бы Структура проекта Haskell или какая-то другая wiki объясняла это.
Ответы
Ответ 1
Прежде всего, я помещаю каждый модуль под Luminosity
Я думаю, что это был хороший шаг. Он разъясняет всем, кто читает код, что эти модули были созданы специально для проекта Luminosity
.
Если вы пишете модуль с целью имитации или улучшения существующей библиотеки или заполнения пробела, в котором вы считаете, что какая-то общая библиотека отсутствует, тогда в этом редком случае отбросьте префикс и назовите его в общем виде. Пример этого см. В разделе экспорта pipes Control.Monad.Trans.Free
, поскольку автор по какой-либо причине не удовлетворен существующими реализации свободных монад.
Тогда я подумал, что Vector и Color довольно независимы и могут быть использованы повторно, поэтому их нужно разделить. Но они подходят к малым, чтобы отделить их от библиотеки (125 и 42 строки соответственно). Куда они должны идти?
Если вы не создаете отдельную библиотеку, то, вероятно, оставьте их в Luminosity.Vector
и Luminosity.Colour
. Если вы делаете отдельные библиотеки, попробуйте отправить электронную почту целевой аудитории этих библиотек и посмотреть, как другие люди считают, что эти библиотеки должны быть названы и классифицированы. Независимо от того, разделите ли вы их на отдельные библиотеки, полностью зависит от вас и насколько вы думаете, что эти отдельные библиотеки могут предоставить другим людям.
Ответ 2
Если ваша программа действительно большая, не организуйте модули в иерархии. Почему бы и нет? Потому что, хотя компьютеры хороши в иерархии, людей нет. Люди хороши в значащих именах. Если вы выбираете хорошие имена, вы можете легко обрабатывать 150 модулей в плоском пространстве имен.
Мне казалось, что [пространство с плоским пространством] не хватает организации.
Иерархическая организация не является самоцелью. Чтобы оправдать разделение модулей на иерархию, вам нужна причина. Хорошие причины, как правило, связаны с скрытием или повторным использованием информации. Когда вы скрываете информацию, вы находитесь на полпути к библиотечному дизайну, и когда вы говорите о повторном использовании, вы фактически создаете библиотеку. Чтобы превратить большую программу в "меньшую программу плюс библиотеку", это хорошая стратегия для разработки программного обеспечения, но похоже, что вы только начинаете, и ваша программа еще не настолько велика, чтобы развиваться таким образом.
Эти проблемы в значительной степени не зависят от языка программирования, который вы используете. Я рекомендую прочитать некоторые из работ Дэвида Парнаса по продуктам и семействам программ, а также Матиас Блюм недооценил документ Иерархическая модульность. Эти работы дадут вам более конкретные идеи о том, когда иерархия начинает служить цели.