繁体   English   中英

我可以概括使用类型标签的 GADT 吗?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM