Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List Haskell-帮助理解函数_List_Haskell_Recursion_Mapping - Fatal编程技术网

List Haskell-帮助理解函数

List Haskell-帮助理解函数,list,haskell,recursion,mapping,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],

我有一个神秘的功能,我很难理解:

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]]
通过查看结果,我可以看到它计算列表中所有可能的数字组合,但不是所有可能的排列……我认为

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

我想我已经开始-->将(1:)映射到[2],产生[1,2],但在这一点上,我很困惑递归是如何工作的,我是仍然映射(1:)还是现在映射(2:),以及到底映射到什么

如果有人能帮助我一步一步地解释(使用提供的示例之一)这个函数是如何工作的(使用映射和集合递归),那将非常感谢


谢谢大家!

您的神秘函数是计算其输入的。

您的神秘函数是计算其输入的。

Haskell将执行所谓的惰性评估,这意味着它只会在需要时从左到右(通常)解决问题。因此,以您的
神秘[1,2]
为例,Haskell将执行以下操作:

sets ++ (map (x:) sets)
评估结果如下:

mystery (2:[]) ++ (map (1:) sets)
此时,我们正在调用
神秘(2:[])

神秘([])
将返回一个空列表

[[]] ++ (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:[]))
最后的
集合
将评估
神秘(2:[])

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

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

行动的真正内容是最后两个部分。Haskell创建一个类似于
[[],[2]]
的列表,然后在每个列表的开头添加一个列表,形成
[[1],[1,2]
,Haskell将执行所谓的惰性评估,这意味着它只会在需要时从左到右(通常)进行计算。因此,以您的
神秘[1,2]
为例,Haskell将执行以下操作:

sets ++ (map (x:) sets)
评估结果如下:

mystery (2:[]) ++ (map (1:) sets)
此时,我们正在调用
神秘(2:[])

神秘([])
将返回一个空列表

[[]] ++ (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:[]))
最后的
集合
将评估
神秘(2:[])

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

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

行动的真正内容是最后两个部分。Haskell创建了一个类似于
[[],[2]]
的列表,然后在每个列表的开头添加一个列表,形成
[[1],[1,2]]

这里是否有
家庭作业
标签?看起来像是家庭作业,实际上不是家庭作业。与学校有关,是的,但不是家庭作业。我正在学习Haskell的一个测试,并试图更好地理解这个例子。
家庭作业
标签在这里合适吗?看起来像是家庭作业,实际上不是家庭作业。与学校有关,是的,但不是家庭作业。我正在学习Haskell的测试,并试图更好地理解这个例子。哇!谢谢你如此彻底的回复!非常感谢。哇!谢谢你如此彻底的回复!非常感谢。