当前位置:  开发笔记 > 小程序 > 正文

创建数据类型和monad时出错和混淆

如何解决《创建数据类型和monad时出错和混淆》经验,为你挑选了1个好方法。

考虑下一段代码:

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进行定义



1> leftaroundab..:

每一个data构造函数必须有一个明确的名称,比如你用了EmptyTile,X,O,Player1Player2.有Board,没有这样的名字; 哈斯克尔认为这是荒谬的

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:monad最重要的是一个仿函数,即在该参数中对某种类型和协变进行参数化的东西.你可以把它变成一个monad,通过用Tile多态的东西替换那些硬编码的字段:

data Board t = Board t t t t t t t t t
    deriving (Functor)

但是ApplicativeMonad实例看起来比你提出的要多一些.

您可能会考虑这样的方法:Board您可以定义索引类型,而不是手动滚动数据结构:

data BoardIndex = Edge0 | Middle | Edge1
type Board t = (BoardIndex, BoardIndex) -> t

那么这将是一个没有任何进一步定义的monad,即函数monad,它具有你可能想要的语义.它往往效率有点低,因为结果实际上并没有存储但总是在现场重新计算,但对于像Tic Tac Toe这样的东西几乎不重要.(通过引入备忘录,您可以在以后轻松提高效率.)

推荐阅读
贴进你的心聆听你的世界
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有