在学习Haskell时,我为自己设置了一个难题,就是编写一个4 X 4 KenKen求解器。这涉及将数字1到4放在4乘4的矩阵中,使得每行和每列包含不同的值。还有 cages ,它基于加法,乘法,除法(仅两个单元格)或减法(仅两个单元格)来约束其中包含的数字。有关完整规则,请参阅wikipedia page on KenKen。
我已经编程了30年,我想知道如何在Haskell中解决这个问题。在这里,我需要一些绝对的初学者建议。
我粗略概述: -
Maybe int
的不可变列表,constraint
创建一个类型类,它可以获取一个单元格列表并返回一个布尔值,如果constranit是否被违反(或者这是否有点OO我应该为这些创建函数?),solve
函数,该函数接收单元格和约束列表solve
将针对每个约束检查单元格,并使用新列表调用自己尝试不同的数字或回溯所以我的问题是,这种方法是否会起作用并且它在Haskell中是不是很常见?你能否建议我如何做一些更实用的功能,而不需要知道任何太高级的东西。我对这是解决这个问题最有效的方法并不感兴趣,因为这只是我自己设定的一个学习练习。
编辑:下面的答案和评论围绕着类型类的需要,所以可能有点我错了。我觉得有必要,所以我可以多态地处理所有不同种类的约束。我相信每个人都在说这是不够的,我只能有一个接受单元格列表并返回布尔值的函数列表。
答案 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 2
或doFunc (*) 1 2
。
我建议的主要是尝试自下而上。我发现它确实有助于构建小函数并构成它们的FP编程哲学。