比方說,我寫了下面的代碼:哈斯克爾 - 解決週期性模塊依賴
遊戲模塊
module Game where
import Player
import Card
data Game = Game {p1 :: Player,
p2 :: Player,
isP1sTurn :: Bool
turnsLeft :: Int
}
播放器模塊
module Player where
import Card
data Player = Player {score :: Int,
hand :: [Card],
deck :: [Card]
}
和卡模塊
module Card where
data Card = Card {name :: String, scoreValue :: Int}
然後我寫一些鱈魚e實現邏輯,讓玩家輪流從他們的手中抽取和打牌,爲他們的分數添加獎勵,直到遊戲結束。
但是,當我完成這段代碼後,我意識到我寫的遊戲模塊很無聊!
我想重構紙牌遊戲,所以當你玩牌時,而不是僅僅增加一個分數,而是該牌可以任意轉換遊戲。
所以,我的Card
模塊更改爲以下
module Card where
import Game
data Card = Card {name :: String,
onPlayFunction :: (Game -> Game)
scoreValue :: Int}
這當然使得模塊導入形成循環。
如何解決此問題?
微不足道的解決方案:
將所有文件移到同一模塊。這很好地解決了這個問題,但是降低了模塊性;我以後不能重複使用相同的卡模塊進行其他遊戲。
模塊保持溶液:
添加類型參數Card
:
module Card where
data Card a = {name :: String, onPlayFunc :: (a -> a), scoreValue :: Int}
添加另一個參數Player
:
module Player where
data Player a {score :: Int, hand :: [card a], deck :: [card a]}
隨着一個最後修改Game
:
module Game where
data Game = Game {p1 :: Player Game,
p2 :: Player Game,
}
這保持了模塊化,但要求我爲我的數據類型添加參數。如果數據結構更深層嵌套,我可能必須添加大量的參數給我的數據,如果我必須將這種方法用於多個解決方案,那麼我最終可能會得到一個難以處理的數量的類型修飾符。
那麼,有沒有其他有用的解決方案來解決這個重構,還是隻有這兩個選項?
我寧願強烈建議避免使用'{ - #SOURCE# - }'/ .hs-boot機制,除非真的有必要。 – leftaroundabout
@leftroundabout:是的,我覺得它很煩瑣,但是有沒有比[wiki](https://wiki.haskell.org/Mutually_recursive_modules)中提到的更有爭議,它們是(imho)不是與小項目相關? –