Haskell 创建数据类型和monad时出现错误和混乱
考虑下一段代码:Haskell 创建数据类型和monad时出现错误和混乱,haskell,Haskell,考虑下一段代码: data Tile = EmptyTile | X | O data Player = Player1 | Player2 instance Show Tile where show EmptyTile = " " show X = "X" show O = "O" data Board = (Tile, Tile, Tile, Tile, Tile, Tile, Tile, Tile, Tile) emptyB
data Tile = EmptyTile | X | O
data Player = Player1 | Player2
instance Show Tile where
show EmptyTile = " "
show X = "X"
show O = "O"
data Board = (Tile, Tile, Tile, Tile, Tile, Tile, Tile, Tile, Tile)
emptyBoard :: Board
emptyBoard = (EmptyTile,EmptyTile,EmptyTile,EmptyTile,EmptyTile,EmptyTile,EmptyTile,EmptyTile,EmptyTile)
instance Monad Board where
return x = x
f >>= x = x
我希望那块板子是单子。但问题是我得到了以下错误-
[1 of 1] Compiling Main ( Main.hs, Main.o )
Main.hs:17:14: error:
Illegal binding of built-in syntax: (,,,,,,,,)
需要更改哪些内容,以便稍后将Board定义为monad您编写的
数据
是指类型
或新类型
:
data Tile = EmptyTile | X | O
data Player = Player1 | Player2
instance Show Tile where
show EmptyTile = " "
show X = "X"
show O = "O"
type Board = (Tile, Tile, Tile, Tile, Tile, Tile, Tile, Tile, Tile)
emptyBoard :: Board
emptyBoard = (EmptyTile,EmptyTile,EmptyTile,EmptyTile,EmptyTile,EmptyTile,EmptyTile,EmptyTile,EmptyTile)
-- this won’t work
instance Monad Board where
return x = x
f >>= x = x
或
同样值得注意的是,tic税收优惠游戏中的棋盘不会是
Monad
。一方面,它需要一个类型参数,另一方面,它显然永远不会满足这些定律。每个数据构造函数必须有一个明确的名称,比如你用清空符,X
,O
,播放器1
和播放器2
给出的名称。对于板
,没有这样的名称;Haskell desugars将此视为
data Board = (,,,,,,,,) Tile Tile Tile Tile Tile Tile Tile Tile Tile
所以在这里,(,,,,,,,)
将是“构造函数名”,但这在Haskell中实际上是不合法的,因此出现了错误
只需选择一个自定义名称,就像无聊一样
data Board = Board Tile Tile Tile Tile Tile Tile Tile Tile Tile
现在,这不可能是一个单子:一个单子主要是一个,也就是说,在某个类型上被参数化,并且在该参数中是协变的。不过,您可以将那些硬编码的平铺字段替换为多态字段,从而使其成为monad:
data Board t = Board t t t t t t t t t
deriving (Functor)
但是Applicative
和Monad
实例看起来比您建议的要复杂一些
您可以考虑这样一种方法:代替手工滚动<代码>板>代码>数据结构,定义一个索引类型:
然后这将是一个没有任何进一步定义的monad,即函数monad,它具有您可能想要的语义。它往往有点低效,因为结果实际上并没有存储,但总是在现场重新计算,但对于像Tic-Tac-Toe这样的东西来说,这几乎无关紧要。(稍后,您可以通过引入
data Board t = Board t t t t t t t t t
deriving (Functor)
data BoardIndex = Edge0 | Middle | Edge1
type Board t = (BoardIndex, BoardIndex) -> t