考虑下一段代码:
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
Run Code Online (Sandbox Code Playgroud)
我希望那个董事会成为一个单子.但问题是我得到以下错误 -
[1 of 1] Compiling Main ( Main.hs, Main.o )
Main.hs:17:14: error:
Illegal binding of built-in syntax: (,,,,,,,,)
Run Code Online (Sandbox Code Playgroud)
需要进行哪些更改才能将Board作为monad进行定义
每一个data
构造函数必须有一个明确的名称,比如你用了EmptyTile
,X
,O
,Player1
和Player2
.有Board
,没有这样的名字; 哈斯克尔认为这是荒谬的
data Board = (,,,,,,,,) Tile Tile Tile Tile Tile Tile Tile Tile Tile
Run Code Online (Sandbox Code Playgroud)
所以在这里,(,,,,,,,,)
将是"构造函数名称",但这在Haskell中实际上并不合法,因此错误.
只需选择一个自定义名称,如无聊
data Board = Board Tile Tile Tile Tile Tile Tile Tile Tile Tile
Run Code Online (Sandbox Code Playgroud)
现在,这不可能是一个monad:monad最重要的是一个仿函数,即在该参数中对某种类型和协变进行参数化的东西.你可以把它变成一个monad,通过用Tile
多态的东西替换那些硬编码的字段:
data Board t = Board t t t t t t t t t
deriving (Functor)
Run Code Online (Sandbox Code Playgroud)
但是Applicative
和Monad
实例看起来比你提出的要多一些.
您可能会考虑这样的方法:Board
您可以定义索引类型,而不是手动滚动数据结构:
data BoardIndex = Edge0 | Middle | Edge1
type Board t = (BoardIndex, BoardIndex) -> t
Run Code Online (Sandbox Code Playgroud)
那么这将是一个没有任何进一步定义的monad,即函数monad,它具有你可能想要的语义.它往往效率有点低,因为结果实际上并没有存储但总是在现场重新计算,但对于像Tic Tac Toe这样的东西几乎不重要.(通过引入备忘录,您可以在以后轻松提高效率.)
归档时间: |
|
查看次数: |
58 次 |
最近记录: |