我是Haskell的新手,有一个工作表问题把我难住了。这个问题要求我定义一个函数,它接受一个元组列表,每个元组包含一个数字子列表,并返回一个元组列表,每个元组包含一对整数。这是预期的输入和输出。
possibles [([1],[2,3,4]),([1,2],[3,4])] ===> [(1,234),(1,243),(1,342),(1,324),(1,423),(1,432),(12,34),(12,43),(21,34),(21,43)]
我尝试使用“Data.List”库中的“permutations”函数和我制作并附在下面的另外两个函数。
x一个一个一个一个x一个一个二个x
2条答案
按热度按时间c2e8gylq1#
欢迎来到 haskell 家庭!2这是一个有趣的问题,可以帮助你发现 haskell 的美丽。
首先,我们先看问题,再进入实施:
1.将
[2,3,4]
转换为[[2,3,4], [2,4,3], [3,2,4], [3,4,2], [4,2,4], [4,3,2]]
1.将
[2,3,4]
转换为234
(您已经实现了这一部分)1.将
([12,21], [34,43])
转换为[(12,34),(12,43),(21,34),(21,43)]
1.把所有的东西都组合在一起(组合真的很强大)
1.重构
其次,这里有2个有用的工具,我建议:
现在让我们尝试实现它。
首先,我们知道输入类型是
[([Int], [Int])]
:现在让我们按照上面提到的步骤。
步骤1称为
permutation :: [a] -> [[a]]
,它不仅适用于Int
,还适用于任何类型的列表。如果你在hoogle中搜索
[a] -> [[a]]
,你可能会发现这个函数,现在回到REPL:对于步骤2,我们现在使用您的代码:
步骤3是使用list comprehension的一个很好的示例:
现在是令人兴奋的部分--合成。首先我们将
step1
和step2
结合起来:注意,你可以专注于函数组合,而不必关心这里的值:
现在,我们将
step3
与step12
组合在一起现在最后一步是一个简单的
map
或fmap
。让我们看看目前为止我们得到了什么:
现在我们通过(
map step123 input
)得到了[[(Int, Int)]]
,我们所要做的就是一个函数把[[a]]
转换成[a]
,让我们在hoogle中搜索它(小心选择一个行为正确的)。因此,让我们将
step4
放在这里,以完成解决方案的第一个版本:注意,我们可以只关注合成,而不考虑价值:
现在让我们看看如何使用列表解析重构
step123
,并将其重命名为getCombinations
:这绝不是最简洁或性能最好的代码,但它是一个良好的开端,我希望您能从中学到一些东西。
你有一个很好的开始,继续努力,享受Haskell:)
qlzsbp2j2#
我们可以先将问题简化为:
因为输入中的每一项都是单独的case。
对于
possible'
,从x
和y
生成所有排列,然后将它们转换为数字就足够了:它以不同的顺序产生结果:
但是,通过实现不同的置换函数,您可以改变生成项的顺序。
适用于:
这将生成 * 1! × 8!+2! × 7!+3! × 6!+4! × 5!+5! × 4!+6! × 3!+7! × 2!+8! × 1!= 2 ×(1! × 8!+2! × 7!+3! × 6!+4! × 5!)= 2 × 57 '600 = 115' 200 *