haskell - 链接类型类、类和实例
问题描述
我正在尝试在 Haskell 中编写一个组合博弈论引擎。有几个关键要素。
任何环境都应该有 3 种行为:产生“基本”状态的能力、在给定动作的情况下推进状态的能力以及产生数字奖励向量的能力。我使用了一个类型类
Environment
来做到这一点。特定游戏(例如下面的 Nim)应该是
Environments
. 我使用这种抽象是因为我想编写需要类型类的函数(例如蒙特卡洛树搜索)Environment
,而不是任何特定的游戏。
为了测试我是否一切正常,我为 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
当我尝试编译时,我收到以下错误,表明我对类型类和实例的理解存在问题:
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
定义中插入太多的类约束,除了奖励是数字的。如何在不失去这种灵活性的情况下修复上述骨架?
解决方案
您需要同时绑定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
推荐阅读
- sql-server - SQL Server - 识别 Varchar 中的十六进制范围
- javascript - How to make a react-strap Button responsive?
- php - 从 PHP 后端访问文件
- json - Json文件中的奇怪方程
- asp.net - 某些 pdf 文件未在 chrome 中完全加载
- vue.js - 如何通过 @storybook/addon-contexts 在 vue js 项目中使用故事书切换语言环境
- c# - c# 获取新类的引用并将其提供给它自己的内联方法
- javascript - 如何使用for of循环获取对象的值
- r - 有人可以帮我理解这个 for 循环在做什么吗?...我是 R 新手
- javascript - 使用 GTM 将 UTM 参数从一个页面传输到另一个页面