Haskell - 帮助理解一个函数

时间:2011-12-12 02:57:47

标签: list haskell recursion mapping

我有这个神秘功能,我无法理解:

mystery :: [a] -> [[a]]
mystery [] = [[]]
mystery (x:xs) = sets ++ (map (x:) sets)
                 where sets = mystery xs

以下是一些结果输入:

mystery [1,2] returns [[],[2],[1],[1,2]]
mystery [1,2,3] returns [[],[3],[2],[2,3],[1],[1,3],[1,2],[1,2,3]]

通过查看结果,我可以看到它计算列表中所有可能的数字组合,但不是所有可能的permeations ......我认为。

我遇到的麻烦实际上是通过递归并理解函数如何获得这些结果。

我想我得到了它的开始 - >将(1 :)映射到[2],得到[1,2],但是在这一点上,我很困惑递归是如何工作的,以及我是否仍然映射(1 :)或现在(2 :),并确切地说到了什么。

如果有人可以通过逐步解释(使用提供的示例之一)如何使用此功能(使用地图和设置递归)来帮助我,那将非常感激!

谢谢!

2 个答案:

答案 0 :(得分:7)

Haskell将执行所谓的延迟评估,这意味着它只能从左到右(通常)需要它们。因此,以mystery [1, 2]为例,Haskell将执行以下操作:

sets ++ (map (x:) sets)

评估为:

mystery (2:[]) ++ (map (1:) sets)

此时,我们正在调用mystery (2:[])

mystery ([]) ++ (map (2:) sets) ++ (map (1:) sets)

mystery ([])将返回一个空的列表列表

[[]] ++ (map (2:) sets) ++ (map (1:) sets)
[[]] ++ (map (2:) mystery []) ++ (map (1:) sets)

所以现在Haskell会尝试在包含空列表的列表中应用函数(2:)

[[]] ++ (2:[[]]) ++ (map (1:) sets)
[[]] ++ [[2]] ++ (map (1:) sets)
[[], [2]] ++ (map (1:) sets)

这是让事情变得更加混乱的地方。

[[], [2]] ++ (map (1:) mystery (2:[]))

最后sets将评估mystery (2:[])

[[], [2]] ++ (map (1:) (sets ++ (map (2:) sets)))
[[], [2]] ++ (map (1:) (mystery [] ++ (map (2:) sets))
[[], [2]] ++ (map (1:) ([[]] ++ (map (2:) mystery []))
[[], [2]] ++ (map (1:) ([[]] ++ (2:[[]]))
[[], [2]] ++ (map (1:) ([[]] ++ [[2]])

现在(1:)将应用于包含空列表的列表,以及包含2的列表:

[[], [2]] ++ (map (1:) ++ [[], [2]])
[[], [2]] ++ [[1], [1, 2]]
[[], [2], [1], [1, 2]]

手术的真正含义在于最后两节。 Haskell创建一个类似[[], [2]]的列表,然后将一个列表添加到每个列表的头部以形成[[1], [1, 2]]

答案 1 :(得分:2)

你的神秘功能是计算其输入的power set