2010-10-23 81 views
6

我正在哈斯克爾寫一個蛇遊戲。這些都是一些事情,我有:我應該在Haskell中製作模塊應該多少?

  • 一個Coord數據類型
  • 一個Line數據類型
  • 一個Rect數據類型
  • 一個Polygon型類,它可以讓我得到一個Rect作爲系列行([Line])。
  • Impassable類型的類,讓我得到了Line一系列COORDS([Coord]),這樣我可以檢測其它Impassable S之間的衝突。
  • A Draw我想繪製到屏幕(HSCurses)的任何類型的類。
  • 最後,我使用QuickCheck,因此我想爲許多這些事情聲明Arbitrary實例。

目前我有很多這些在單獨的模塊,所以我有很多小模塊。我注意到我必須爲它們導入很多它們,所以我有點想知道點。

我對Arbitrary實例特別困惑。當我使用-Wall時,我收到有關孤立實例的警告,但當我將這些實例集中在一個測試文件中時,我的理解是,我可以通過將這些實例放入與定義數據類型的模塊相同的模塊來避免該警告,但隨後我需要到import Test.QuickCheck所有這些模塊看起來很愚蠢,因爲只有在構建測試可執行文件時才需要QuickCheck。

任何有關QuickCheck的具體問題的建議將受到讚賞,關於如何/在哪裏將程序劃分爲模塊的更一般問題的指導將得到讚賞。

回答

1

我通常更多地強調模塊接口,而不是它公開的數據類型。你的一些類型是否有共同的功能?然後我會把它們放在同一個模塊中。

但我的做法可能不是最好的,因爲我通常寫小程序。我建議查看Hackage中的一些代碼來查看軟件包維護人員所做的事情。

如果有按社區評級或下載次數對軟件包進行分類的方法,那將是一個很好的開始。 (我以爲有,但現在我找到了它,我找不到它。)如果沒有,請查看您已使用的軟件包。

+0

有下載的數量和反向依賴關係排名的鏈接在這裏:http://stackoverflow.com/questions/3663550/which-haskell-package-for-json/3663601#3663601 – 2010-10-23 01:32:46

4

你可以吃你的蛋糕,也可以吃它。您可以重新導出模塊。

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

當我有一個完整的抽象 - 即數據類型的含義與其實現不同時,我通常會使用一個模塊。對代碼知之甚少,我可能會將PolygonImpassable組合在一起,也許會使用Collision數據類型來表示它們返回的內容。但是CoordLineRect看起來像很好的抽象,他們可能應該擁有自己的模塊。

+0

任何建議做什麼關於QuickCheck問題? – 2010-10-23 10:54:25

+1

這是一個難題,實際上我一直在努力。我認爲你現在最好的選擇就是像John建議的那樣處理孤兒。我認爲正確的做法是擁有「分發組合器」,所以不是「實例任意座標」,而是有一個「任意座標::分佈座標」函數。在測試中使用起來更麻煩一些,但它更靈活和模塊化,因爲對於同一類型可以有多個分佈(特別是,如果定義了兩個不同的分佈,那麼這個世界不會爆炸)。 – luqui 2010-10-23 18:44:21

2

出於測試目的,我爲Arbitrary實例使用單獨的模塊。雖然我通常會避免孤兒實例,但是這些模塊只有在構建測試可執行文件時纔會生成,因此我不介意孤兒或它不是乾淨的。您還可以使用-fno-warn-orphans來僅禁用此警告消息。

+0

你有一個單獨的模塊來處理'Arbitrary'實例嗎? – 2010-10-23 10:46:25

+0

@Ollie Saunders - 這取決於項目的規模。對於較小的項目,我使用兩個模塊進行測試:其中一個具有「任意」實例和其他額外代碼(如有必要),另一個模塊具有QuickCheck屬性。對於大型項目,我喜歡Snap框架中使用的佈局。他們爲每個包含任意實例和屬性測試的常規模塊都有一個測試模塊。 – 2010-10-23 13:20:30

0

QuickCheck的一個解決方案是使用C預處理器在測試時選擇性地啓用任意實例。您將任意實例直接放入主模塊中,但用預處理器宏包裝它們,然後將「測試」標誌放入Cabal文件中。