Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell-解析循环模块依赖关系_Haskell_Cyclic Dependency - Fatal编程技术网

Haskell-解析循环模块依赖关系

Haskell-解析循环模块依赖关系,haskell,cyclic-dependency,Haskell,Cyclic Dependency,假设我编写了以下代码: 游戏模块 module Game where import Player import Card data Game = Game {p1 :: Player, p2 :: Player, isP1sTurn :: Bool turnsLeft :: Int } 播放器模块 module Player where import

假设我编写了以下代码:

游戏模块

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}
然后我编写了一些代码来实现这样的逻辑:玩家轮流从手上抽牌和打牌,为他们的分数增加奖金,直到游戏结束为止

然而,在完成这段代码后,我意识到我编写的游戏模块很无聊

我想重构纸牌游戏,这样当你玩一张牌时,而不是仅仅添加一个分数,而是纸牌任意改变游戏

因此,我将
模块更改为以下内容

module Card where
import Game
data Card = Card {name :: String, 
                  onPlayFunction :: (Game -> Game)            
                  scoreValue :: Int}
这当然会使模块导入形成一个循环

如何解决这个问题

简单的解决方案:

将所有文件移动到同一模块。这很好地解决了问题,但减少了模块化;我以后不能在其他游戏中重复使用相同的卡模块

模块维护解决方案:

将类型参数添加到

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]}
游戏进行最后一次修改

module Game where
data Game = Game {p1 :: Player Game,
                  p2 :: Player Game,
                 }
这保持了模块化,但需要向数据类型添加参数。如果数据结构嵌套得更深,我可能不得不向数据中添加大量参数,如果我不得不将此方法用于多个解决方案,那么最终可能会出现数量庞大的类型修饰符

那么,有没有其他有用的解决方案来解决此重构问题,或者这是仅有的两个选项?

您的解决方案(添加类型参数)不错。您的类型变得更加通用(如果需要,您可以使用
Card OtherGame
),但是如果您不喜欢额外的参数,您可以:

  • 编写一个模块
    CardGame
    ,其中包含(仅)相互递归的数据类型,并将此模块导入其他模块,或
  • ghc
    中,使用
    {-#SOURCE#-}
    杂注

最后一个解决方案需要编写一个
Card.hs boot
文件,其中包含
Card.hs
中的类型声明子集

我宁愿强烈建议避免
{-#SOURCE#-}
/.hs启动机制,除非它真的是必要的。@leftroundound:是的,我觉得它很烦琐和不舒服,但是除了中提到的那些(imho)与小项目不太相关的机制之外,还有其他反对它的理由吗?