我正在尝试在 Haskell 中实现一个函数,该函数返回一个列表,其中包含玩家的所有可能动作。该函数的唯一参数是一个字符串,由棋盘的实际状态(在福赛斯-爱德华兹符号中)组成,后跟移动的玩家(b/w)。
符号示例:rnbqkbnr/pppppp/8/8/8/PPPPPPP/rnbqkbnr w(起始板状态)
移动以[origin]-[destination]格式的字符串传输。目的地始终是形式[column][row]的位置,其中左下方格称为a1,右上方格称称为h8。例如,移动可以是移动“b3-c4”。(无城堡/城堡)。
在Java中,我会使用2d数组作为电路板,但在Haskell中我找不到类似的解决方案(我是函数式编程的新手)。
用什么样的方式/数据结构来表示棋盘比较好?
<code>数据。向量具有按索引进行的恒定时间查找。
棋盘可以表示为< code>Vector (Vector(可能是棋子))。要定义< code>Piece,请参见ADTs
存储板状态有两个主要选项。第一个是可能
的2D列表,其中一个部分将表示为,例如只是$Piece Black King
,一个空白方块将表示为无
。这优化了确定方块是否被占用而不是列出块所在的位置(如果您计划稍后添加渲染,这可能很重要):
type Board = Vector (Vector (Maybe Piece))
data Piece = Piece { color :: Color
, type :: PieceType }
第二个选项是存储片段列表及其位置。此实现枚举所有块的位置更快,但检查特定正方形上是否有块的速度较慢:
type Pieces = [Placement]
type Placement = { position :: Position
, piece :: Piece }
data Position =
Pos { rank :: Int
, file :: Int }
deriving (Show, Eq)
data Piece =
Piece { color :: Color
, ptype :: PieceType }
deriving Show
编辑:值得注意的是,使用8x8网格和板上最多32个棋子,除非您进行大量计算,否则无论哪种方式对性能的影响都将很小。
我对Haskell比较陌生,我正在努力找到一种实现Haskell的span函数的方法。然而,我的问题比这更一般,因为我不知道如何使函数返回包含所需元素的列表或元组列表。我对列表的问题,例如: 是我不能让函数在列表列表中的第一个列表中添加一个元素。我只知道如何将另一个列表附加到列表列表中。 简而言之,如果您向我解释如何实现span函数,我希望这一切都会清楚。
:101:22:ERROR:•在表达式“count words”的第一个参数中的“hello”中,即表达式:countWords[“hello”,“hello”,“world”]中的“[”hello“,”hello“,”world“]”中,无法将预期类型“Char”与实际类型“[Char]”匹配• :101:31:error:•在表达式“count words”的第一个参数中的“world”中,即
Haskell(使用编译器)比您预期的要快得多。如果使用得当,它可以接近低级语言。(Haskellers最喜欢做的一件事是尝试将C语言的5%以内(甚至超过它,但这意味着您使用的是一个低效的C程序,因为GHC将Haskell编译为C)。)我的问题是,为什么?
Scala开发人员学习IO单元体,因此一般的蹦床技术对于不可能进行尾调用优化的递归是必要的,我想知道Haskell是如何避免它的。 我知道Haskell是一种懒惰的语言,但是我想知道是否有人可以再详细说明一下。 例如,为什么ForeverM stackoverflow不在Scala中运行?好吧,我可以回答蹦床,我可以找到实际的代码,在图书馆和博客。我自己居然实现了一个基本的蹦床来学习。 在哈斯克尔
GHC能否简化id=(\(a,b)- 更复杂的情况呢: GHC将简化映射到映射中? 我试图使用简单的beta缩减,但由于糟糕的模式匹配,这些术语看起来是不可缩减的。 因此,我很好奇GHC的优化技术如何处理这个问题。
在Haskell中,下面的代码打印“[1,2,3,4,5”: 但是在Frege中,它抛出,代码如下: 这里唯一的区别是函数,它是从转换为和FWIW,函数是热切的。为什么整个表达式不能像Haskell中那样懒惰呢?在这里有可能实现类似弗雷格哈斯克尔的东西吗?