fuz*_*fuz 7 monads haskell abstraction typeclass monad-transformers
目前,我尝试编写一个小游戏程序(Skat)作为业余爱好项目.斯卡特是一个招人游戏,两名球员对阵一名球员.由于有不同类型的玩家(lokal播放器,网络播放器,计算机等),我想将界面抽象给玩家.
我的基本想法是使用一个类型类Player,它定义了所有类型的东西,一个玩家必须做和知道(玩牌,获得通知谁赢得了这个技巧等).然后,整场比赛仅通过一个函数来完成playSkat :: (Player a, Player b, Player c) => a -> b -> c -> IO (),其中a,b并且c可能是不同类型的球员.然后,玩家可以以实现定义的方式做出反应.lokal播放器会在终端上收到一些消息,网络播放器可能会通过网络发送一些信息,而计算机播放器可能会计算出新策略.
因为玩家可能想要做一些IO并且肯定想要某种状态来跟踪私人事物,所以它必须存在于某种Monad中.所以我Player想要像这样定义类:
class Player p where
  playCard :: [Card] -> p -> IO (Card,p)
  notifyFoo :: Event -> p -> IO p
  ...
这种模式似乎与状态变换器非常相似,但我不知道如何处理它.如果我把它作为额外的monad-transformer写在IO之上,那么我在一天结束时会有三个不同的monad.我怎样才能以良好的方式编写这个抽象?
为了澄清,我需要的是,通常的控制流程应该是这样的:
当玩一个技巧时,第一个玩家打牌,然后是第二个,最后是第三个.为此,逻辑需要playCard为每个玩家执行函数trice.之后,逻辑决定哪个玩家赢得了技巧并将赢得的信息发送给所有玩家.
首先,请记住,类型类的主要目的是允许重载函数,即可以使用不同类型的单个函数.你真的不需要这样,所以你最好使用记录类型
data Player = Player { playCard :: [Card] -> IO (Card, Player), ... }
其次,一些玩家需要IO的问题和一些不能用自定义monad解决的问题.我已经为TicTacToe游戏编写了相应的示例代码,这是我的操作包的一部分.