我是堆栈溢出和Haskell的新手,所以请告诉我是否还有另一种方法!
这是这个堆栈溢出问题的重演,Haskell Recursion Subsets,但是这个问题得到的答案并没有真正帮助我,我仍然对这个问题中递归的工作方式感到困惑。这是我尝试重新开始此问题的对话。
这是问题:
我对以下代码片段中的递归如何工作感到困惑:
subsets :: [a] -> [[a]]
subsets [] = [[]]
subsets (x:xs) = [zs | ys <- subsets xs, zs <- [ys, (x:ys)]]
此代码的输出是:
*Main> subsets [1,2,3]
[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
我了解子集是如何递归调用的,以及如何获取子集[] = [[]]
,但我对如何返回列表列表以及如何返回诸如[1]
,{{1 }}和[1,3]
。
再次,我是堆栈溢出的新手,所以除了重复问题之外,是否还有更好的方法可以让我知道。
答案 0 :(得分:3)
让我们首先澄清subsets [3]
。请记住,ys <- [ [] ]
意味着ys
承担列表[ [] ]
中的每个元素,其中仅包含一个元素[]
。
subsets (3:[])
=> [zs | ys <- subsets [] ...
=> [zs | ys <- [ [] ] ...
=> [zs | ys <- [ [] ], zs <- [[], (3:[])]]
= [[], [3]] -- zs takes on each element of [[], (3:[])]
现在让我们忽略“实际上”正在发生的事情,并将其逻辑化为文字。
subsets (x:xs) = [zs | ys <- subsets xs, zs <- [ys, (x:ys)]]
表示:
Aggregate all zs
where ys takes on in turn each of the subsets of the list without x,
and for each ys,
zs takes on the subset ys, and the subset ys and x together
例如:
subsets [2,3]
=> ys takes on in turn each of the subsets of the list without 2
=> [[], [3]]
=> for each ys,
zs takes on the subset ys, and the subset ys and 2 together
=> [[], [2], [3], [2,3]]