我应该在 Haskell 中将 make 模块制作多小?

发布于 2024-09-28 20:12:08 字数 829 浏览 9 评论 0原文

我正在用 Haskell 写一个贪吃蛇游戏。这些是我拥有的一些东西:

  • Coord 数据类型
  • A Line 数据类型
  • A Rect 数据类型
  • A Polygon 类型类,它允许我获取作为一系列线 ([Line]) 的 Rect
  • 一个 Impassable 类型类,允许我获取作为一系列坐标 ([Coord]) 的 Line,以便我可以检测其他坐标之间的碰撞无法通行
  • 一个 Draw 类型类,用于我想要绘制到屏幕上的任何内容 (HSCurses)。
  • 最后,我使用 QuickCheck,所以我想为很多这样的事情声明 Arbitrary 实例。

目前我在单独的模块中有很多这样的模块,所以我有很多小模块。我注意到我必须为彼此导入很多,所以我有点想知道这是什么意思。

我对任意实例特别困惑。使用 -Wall 时,当我将这些实例放在一个测试文件中时,我会收到有关孤立实例的警告,我的理解是,我可以通过将这些实例放在与数据类型相同的模块中来避免该警告已定义,但随后我需要为所有这些模块导入 Test.QuickCheck ,这看起来很愚蠢,因为仅在构建测试可执行文件时才需要 QuickCheck。

任何有关 QuickCheck 特定问题的建议以及有关如何/在何处将程序划分为模块的更一般问题的指导都将受到赞赏。

I'm writing a snake game in Haskell. These are some of the things I have:

  • A Coord data type
  • A Line data type
  • A Rect data type
  • A Polygon type class, which allows me to get a Rect as a series of lines ([Line]).
  • An Impassable type class that allows me to get a Line as a series of Coords ([Coord]) so that I can detect collisions between other Impassables.
  • A Draw type class for anything that I want to draw to the screen (HSCurses).
  • Finally I'm using QuickCheck so I want to declare Arbitrary instances for a lot of these things.

Currently I have a lot of these in separate modules so I have lots of small modules. I've noticed that I have to import a lot of them for each other so I'm kind of wondering what the point was.

I'm particularly confused about Arbitrary instances. When using -Wall I get warnings about orphaned instances when I but those instances together in one test file, my understanding is that I can avoid that warning by putting those instances in the same module as where the data type is defined but then I'll need to import Test.QuickCheck for all those modules which seems silly because QuickCheck should only be required when building the test executable.

Any advice on the specific problem with QuickCheck would be appreciated as would guidance on the more general problem of how/where programs should be divided into modules.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

音栖息无 2024-10-05 20:12:08

你可以鱼与熊掌兼得。您可以重新导出模块。

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

每当我有一个完整的抽象时,即当数据类型的含义与其实现不同时,我通常会使用模块。对您的代码知之甚少,我可能会将 PolygonImpassable 组合在一起,也许会创建一个 Collision 数据类型来表示它们返回的内容。但是,Coord、Line 和 Rect 似乎是很好的抽象,它们可能值得拥有自己的模块。

You can have your cake and eat it too. You can re-export modules.

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

I usually use a module whenever I have a complete abstraction -- i.e. when a data type's meaning differs from its implementation. Knowing little about your code, I would probably group Polygon and Impassable together, perhaps making a Collision data type to represent what they return. But Coord, Line, and Rect seem like good abstractions and they probably deserve their own modules.

放手` 2024-10-05 20:12:08

出于测试目的,我对 Arbitrary 实例使用单独的模块。尽管我通常会避免孤立实例,但这些模块仅在构建测试可执行文件时构建,因此我不介意孤立实例或它不是 -Wall 干净的。您还可以使用 -fno-warn-orphans 来禁用此警告消息。

For testing purposes, I use separate modules for the Arbitrary instances. Although I generally avoid orphan instances, these modules only get built when building the test executable so I don't mind the orphans or that it's not -Wall clean. You can also use -fno-warn-orphans to disable just this warning message.

樱花细雨 2024-10-05 20:12:08

我通常更强调由它公开的函数定义的模块接口,而不是它公开的数据类型。您的某些类型是否共享一组通用的功能?然后我会把它们放在同一个模块中。

但我的做法可能不是最好的,因为我通常编写小程序。我建议查看 Hackage 中的一些代码,看看包维护者做了什么。

如果有一种方法可以根据社区评级或下载次数对软件包进行排序,那么这将是一个很好的起点。 (我以为有,但现在我寻找它,我找不到它。) 如果失败,请查看您已经使用的软件包。

I generally put more emphasis on the module interface as defined by the functions it exposes rather than the data types it exposes. Do some of your types share a common set of functions? Then I would put them in the same module.

But my practise is probably not the best since I usually write small programs. I would advise looking at some code from Hackage to see what package maintainers do.

If there were a way to sort packages by community rating or number of downloads, that would be a good place to start. (I thought there was, but now that I look for it, I can't find it.) Failing that, look at packages that you already use.

情定在深秋 2024-10-05 20:12:08

QuickCheck 的一种解决方案是在测试时使用 C 预处理器有选择地启用任意实例。您将任意实例直接放入主模块中,但用预处理器宏包装它们,然后将“测试”标志放入 Cabal 文件中。

One solution with QuickCheck is to use the C preprocessor to selectively enable the Arbitrary instances when you are testing. You put the Arbitrary instances straight into your main modules but wrap them with preprocessor macros, then put a "test" flag into your Cabal file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文