在学习 Haskell 时,我为自己设置了一个难题,那就是编写一个 4 X 4 KenKen 求解器。这涉及将数字 1 到 4 放置在 4 x 4 矩阵中,这样每一行和每一列都包含不同的值。还有一些笼子根据加法、乘法、除法(仅两个单元格)或减法(仅两个单元格)来限制其中包含的数字。有关完整规则,请参阅KenKen 上的维基百科页面。
我已经进行了 30 年的命令式编程,我想知道如何在 Haskell 中解决这个问题。作为一个绝对的初学者,我在这里需要一些建议。
我的粗略概述:-
- 目前,只需硬编码约束和任何起始数字,以避免必须学习如何进行 IO 和解析,
- 暂时将其保持在 4 x 4 以使生活更简单,
- 将单元格视为
Maybe int
长度为 16 的不可变列表, - 创建一个类型类,
constraint
它可以获取一个单元格列表并返回一个布尔值是否违反了约束(或者这有点面向对象,我应该为这些创建函数?), - 约束会说位置 1、2 和 5 中的单元格必须加起来为 6。函数将获取一个单元格列表,它将返回 true 或 false,
- 编写加、减、除、乘和唯一的约束,
- 创建递归
solve
函数,接收单元格和约束列表, solve
将根据每个约束检查单元格,并使用新列表调用自身,尝试不同的数字或回溯
所以我的问题是,这种方法看起来是否可行,并且在 Haskell 中是惯用的吗?你能建议我如何做一些更实用的东西而不需要知道任何太高级的东西。我对这是解决此问题的最有效方法不感兴趣,因为这只是我自己设定的学习练习。
编辑:下面的答案和评论围绕着对类型类的需求,所以这可能是我弄错了。我觉得需要它,这样我就可以多态地处理所有不同类型的约束。我相信每个人都在说这是不够的,我可以只拥有一个接受单元格列表并返回布尔值的函数列表。