问题描述
我正在尝试用Haskell编写组合博弈论引擎.有几个关键要素.
I'm attempting to write a combinatorial game theory engine in Haskell. There are a few key elements.
-
任何环境都应具有3种行为:产生基础"行为的能力.状态,在给定动作下推进状态的能力以及产生数字奖励向量的能力.我已经使用类型类
Environment
来做到这一点.
特定游戏(例如下面的Nim)应为 Environments
的实例.我使用这种抽象是因为我想编写需要 Environment
类型类而不是任何特定游戏的函数(例如Monte Carlo Tree Search).
Specific games (e.g. Nim below) should be instances of Environments
. I'm using this abstraction because I'll want to write functions (e.g. Monte Carlo Tree Search) that require the Environment
typeclass, not any specific game.
为了证明我没事,我为Nim游戏编写了以下跟踪程序.
To test out that I have it all right, I've written the below tracer program for the game of Nim.
class Environment e where
baseState :: e -> s
nextState :: e -> s -> a -> s
reward :: (Num r) => e -> s -> a -> [r]
data Game = Game { players :: Int
, initial_piles :: [Int]
} deriving (Show)
data State = State { player :: Int
, piles :: [Int]} deriving (Show)
instance Environment Game where
baseState game = State{player=0, piles=initial_piles game}
nextState game state action = State{player=0, piles=piles state}
reward game state action = [0, 0]
newGame :: Int -> [Int] -> Game
newGame players piles = Game{players=players, initial_piles=piles}
main = do
print "Hello, world!"
let game = newGame 2 [3,4,5]
print game
尝试编译时,出现以下错误,表明我对类型类和实例的理解存在问题:
When I attempt to compile, I get the following error indicating an issue with my understanding of typeclasses and instances:
randm@soundgarden:~/Projects/games/src/Main$ ghc -o basic basic.hs
[1 of 1] Compiling Main ( basic.hs, basic.o )
basic.hs:15:22: error:
• Couldn't match expected type ‘s’ with actual type ‘State’
‘s’ is a rigid type variable bound by
the type signature for:
baseState :: forall s. Game -> s
at basic.hs:15:5-13
• In the expression: State {player = 0, piles = initial_piles game}
In an equation for ‘baseState’:
baseState game = State {player = 0, piles = initial_piles game}
In the instance declaration for ‘Environment Game’
• Relevant bindings include
baseState :: Game -> s (bound at basic.hs:15:5)
|
15 | baseState game = State{player=0, piles=initial_piles game}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
basic.hs:16:35: error:
• Couldn't match expected type ‘s’ with actual type ‘State’
‘s’ is a rigid type variable bound by
the type signature for:
nextState :: forall s a. Game -> s -> a -> s
at basic.hs:16:5-13
• In the expression: State {player = 0, piles = piles state}
In an equation for ‘nextState’:
nextState game state action
= State {player = 0, piles = piles state}
In the instance declaration for ‘Environment Game’
• Relevant bindings include
state :: s (bound at basic.hs:16:20)
nextState :: Game -> s -> a -> s (bound at basic.hs:16:5)
|
16 | nextState game state action = State{player=0, piles=piles state}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
除了奖励是数字奖励外,我不想在 Environment
定义中插入太多的类约束.如何在不失去灵活性的情况下修复以上框架?
I don't want to insert too many class constraints into the Environment
definition, other than the reward being numeric. How do I fix the above skeleton without losing this flexibility?
推荐答案
您需要同时绑定 e
和 s
:
{-# LANGUAGE MultiParamTypeClasses #-}
class Environment e s where
baseState :: e -> s
nextState :: e -> s -> a -> s
reward :: (Num r) => e -> s -> a -> [r]
data Game = Game { players :: Int
, initial_piles :: [Int]
} deriving (Show)
data State = State { player :: Int
, piles :: [Int]} deriving (Show)
instance Environment Game State where
baseState game = State{player=0, piles=initial_piles game}
nextState game state action = State{player=0, piles=piles state}
reward game state action = [0, 0]
newGame :: Int -> [Int] -> Game
newGame players piles = Game{players=players, initial_piles=piles}
main = do
print "Hello, world!"
let game = newGame 2 [3,4,5]
print game
这篇关于链接类型类,类和实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!