[英]Can I generalize GADTs that use type tags?
我在 Haskell 中编写了一个 alpha-beta 搜索,它使用NextMoveTag
类型系列来确保游戏状态和从该游戏状态生成的移动对轮到它的玩家有效:
{-# LANGUAGE GADTs, EmptyDataDecls, DataKinds, TypeFamilies #-}
data MoveTag = ComputerMoveTag | PlayerMoveTag
type family NextMoveTag a where
NextMoveTag PlayerMoveTag = ComputerMoveTag
NextMoveTag ComputerMoveTag = PlayerMoveTag
data Move (t :: MoveTag) where
ComputerMove :: CardFace -> Row -> Col -> Move ComputerMoveTag
PlayerMove :: Direction -> Move PlayerMoveTag
data Game (t :: MoveTag) where
PlayerTurnGame :: Board -> Deck -> Game PlayerMoveTag
ComputerTurnGame :: Board -> Deck -> Move PlayerMoveTag -> Game ComputerMoveTag
staticEvaluator :: (Num f) => Game t -> f
nextGameStates :: Game t -> [(Move t, Game (NextMoveTag t))]
现在我想概括一下代码,以便我可以插入任何游戏,即
class Minimaxable g where
staticEvaluator :: ???
nextGameStates :: ???
但是我该如何写类型呢? 我可以吗?
我在尝试编写此代码时遇到的一个问题是, alphabeta
第一步是通过对g
进行模式匹配来检查轮到谁了:
alphabeta depth alpha beta game@(PlayerTurnGame _ _) = ...
这取决于您所说的能够插入“任何游戏”是什么意思。 每个游戏都会有一个MoveTag
表示轮到谁了吗? 如果是这样,那么您可以给g
一个 kind 签名并将类型类定义为
class Minimaxable (g :: MoveTag -> *) where
type GameMove g :: MoveTag -> *
staticEvaluator :: Num f => g t -> f
nextGameStates :: g t -> [(GameMove g t, g (NextMoveTag t))]
Move
类型作为关联类型同义词插入,因为它可能会因不同类型的游戏而异。
现在您可以将现有游戏类型的实例定义为
instance Minimaxable Game where
type GameMove Game = Move
staticEvaluator = ...
nextGameStates = ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.