gpt4 book ai didi

Haskell - 解决循环模块依赖

转载 作者:行者123 更新时间:2023-12-04 07:34:40 24 4
gpt4 key购买 nike

假设我编写了以下代码:

一个游戏模块

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}

然后我编写了一些代码来实现玩家轮流从手中抽牌和打牌的逻辑,以增加他们的分数,直到游戏轮流结束。

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

我想重构纸牌游戏,所以当你玩纸牌时,不仅仅是添加分数,而是纸牌任意改变游戏。

所以,我改变了 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,
}

这保持了模块化,但需要我向我的数据类型添加参数。如果数据结构嵌套得更深,我可能不得不向我的数据添加大量参数,并且如果我不得不将这种方法用于多个解决方案,我最终可能会得到数量庞大的类型修饰符。

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

最佳答案

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

  • 写一个模块CardGame包含(仅)您的相互递归数据类型,并将此模块导入其他数据类型,或
  • ghc , 使用 {-# SOURCE #-}编译到 break the circular dependency

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

    关于Haskell - 解决循环模块依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36978780/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com