带有foldr的Haskell子列表

时间:2017-05-24 22:54:43

标签: haskell combinations fold

我正在尝试在haskell中创建一个函数但我的目标是通过使用foldr over list来实现它,这是一个例子:

sublistas [5,1,2] 
 [[],[2],[1],[1,2],[5],[5,2],[5,1],[5,1,2]]

效率不是问题。到目前为止我尝试的是错误:

  

无法构建无限型......

sublistas = foldr (\x rs -> [x] ++ map (x:) rs) [[]]

我试了很久,也许有人可以在这里给我一些想法?

1 个答案:

答案 0 :(得分:2)

您可以使用:

foldr (\x rs -> rs ++ map (x:) rs) [[]]

例如:

Prelude> foldr (\x rs -> rs ++ map (x:) rs) [[]] [5,1,2]
[[],[2],[1],[1,2],[5],[5,2],[5,1],[5,1,2]]

建议的foldr因此如下工作:我们从[[]]开始。现在,对于元素x,我们生成已生成的所有列表的连接(在第一步[]中,并且这些列表以元素为前缀,因此[2])。

因此,在第一步之后,我们获得[[],[2]]。接下来我们再次折叠,现在我们生成[[],[2],[1],[1,2]]。最后,我们还使用5,结果为[[],[2],[1],[1,2],[5],[5,2],[5,1],[5,1,2]]

上述解释必须以懒惰的方式看待:除非必要,否则rs不必计算(第一),

您的lambda表达式\x rs -> [x] ++ map (x:) rs不正确有两个原因:

  • [x]是一个包含您提供的列表的的列表,而不是您提供的项目列表的列表,因此类型错误;和
  • 您不应该在结果中添加[x]:您传递已生成的所有元素以及您在x之前添加的所有元素。