Haskell 长度k的子集?

Haskell 长度k的子集?,haskell,Haskell,下面的代码以优化的方式工作,我很想理解它,但失败了。我明白第一行,但第二行我迷路了。如果有人能用C或Python来解释它,那将是一个很好的想法,甚至是一般的想法。多谢各位 combinations :: Int -> [a] -> [[a]] combinations k xs = combinations' (length xs) k xs where combinations' n k' l@(y:ys) | k' == 0 = [[]] | k' &

下面的代码以优化的方式工作,我很想理解它,但失败了。我明白第一行,但第二行我迷路了。如果有人能用C或Python来解释它,那将是一个很好的想法,甚至是一般的想法。多谢各位

combinations :: Int -> [a] -> [[a]]
combinations k xs = combinations' (length xs) k xs
  where combinations' n k' l@(y:ys) 
    | k' == 0   = [[]] 
    | k' >= n   = [l] 
    | null l    = [] 
    | otherwise = map (y :) (combinations' (n - 1) (k' - 1) ys) 

Python中的等效项。请注意,这在CPython中非常糟糕,因为递归在那里实现得非常糟糕,在所有类型的Python中都非常糟糕,因为列表的构造方式不同(
1:[2,3,4])
在Haskell中非常简单,但在Python中执行同样的操作需要一些
出列
或丑陋的
[1]+[2,3,4]
东西)

输入import TypeVar,List
A=TypeVar('A')
def组合(k:int,xs:List[A])->List[List[A]:
def帮助器(n:int,k2:int,lst:List[A])->List[List[A]:
#基本情况
如果k2==0:如果请求的子序列长度为零,则返回[]
elif k2>=n:如果请求的子序列长度大于整个序列,则返回[lst]#
elif not lst:如果序列本身为空,则返回[]#
y、 ys=lst[0],lst[1:]
返回[[y]+辅助对象中的rest for rest(n-1,k2-1,ys)]
返回帮助器(len(xs)、k、xs)
注意,在哈斯克尔监狱里过度使用警卫让我觉得有点难看。我可能会改写为:

组合::Int->[a]->[[a]]
组合kxs=组合(长度xs)kxs
哪里
组合'\u0.[]]
组合'.[]=[]
组合n k l@(y:ys)
|k'>=n=[l]
|否则=映射(y:)(组合(n-1)(k'-1)ys)

有一种简单的替代方法与Khuldraeseth na'Barya提供的模式匹配等效:


你的回答也回答了我的问题,我会把它标记为重复的,但是如果你想把它也添加到那里,我认为赏金应该是你的
subsetsOfLength 0 _  = [[]]
subsetsOfLength _ [] = []
subsetsOfLength n (x:xs) = map (x:) (subsetsOfLength (n-1) xs) ++ subsetsOfLength n xs