在编写Ken-Ken解算器时,初学者对惯用Haskell的建议

时间:2013-10-31 10:32:41

标签: haskell idiomatic

在学习Haskell时,我为自己设置了一个难题,就是编写一个4 X 4 KenKen求解器。这涉及将数字1到4放在4乘4的矩阵中,使得每行和每列包含不同的值。还有 cages ,它基于加法,乘法,除法(仅两个单元格)或减法(仅两个单元格)来约束其中包含的数字。有关完整规则,请参阅wikipedia page on KenKen

我已经编程了30年,我想知道如何在Haskell中解决这个问题。在这里,我需要一些绝对的初学者建议。

我粗略概述: -

  • 目前,只需对约束和任何起始数字进行硬编码,以避免必须学习如何进行IO和解析,
  • 暂时将它保持在4乘4,以简化生活,
  • 将单元格视为长度为16的Maybe int的不可变列表,
  • constraint创建一个类型类,它可以获取一个单元格列表并返回一个布尔值,如果constranit是否被违反(或者这是否有点OO我应该为这些创建函数?),
  • 一个约束会说类似位置1,2和5中的单元格必须加起来为6.函数会获取一个返回true或false的单元格列表,
  • 编写加号,减号,除法,乘法和唯一的约束,
  • 创建一个递归solve函数,该函数接收单元格和约束列表
  • solve将针对每个约束检查单元格,并使用新列表调用自己尝试不同的数字或回溯

所以我的问题是,这种方法是否会起作用并且它在Haskell中是不是很常见?你能否建议我如何做一些更实用的功能,而不需要知道任何太高级的东西。我对这是解决这个问题最有效的方法并不感兴趣,因为这只是我自己设定的一个学习练习。

编辑:下面的答案和评论围绕着类型类的需要,所以可能有点我错了。我觉得有必要,所以我可以多态地处理所有不同种类的约束。我相信每个人都在说这是不够的,我只能有一个接受单元格列表并返回布尔值的函数列表。

1 个答案:

答案 0 :(得分:3)

这听起来很不错,但你认为约束是函数而不是类型类是正确的。在haskell中,接口的工作分为两部分。 Typeclasses处理这个函数可以采用任何实现此接口部分的类型。一个例子是Show类型类。通过实现Show类类,您的数据类型支持show(to string)函数。这意味着print现在将打印您的类型的实例。

实现接口的接口概念的一部分,以便您可以具有相同功能的多个实现,这是通过高阶函数而不是附加到不同类型的相同命名函数来处理的。作为此doFunc opp a b = opp a b的示例,它将具有类型(a - > b - > c) - > a - > b - > C。然后,此函数可以使用任意两个操作数函数,并将其应用为doFunc (+) 1 2doFunc (*) 1 2

我建议的主要是尝试自下而上。我发现它确实有助于构建小函数并构成它们的FP编程哲学。