【问题标题】:Haskell Recursion SubsetsHaskell 递归子集
【发布时间】:2017-02-06 09:24:51
【问题描述】:

我是 Haskell 的新手。我发现很难理解下面的递归子程序。它的评估方式是什么?

subset :: [a] -> [[a]]
subset [] = [[]]
subset (x:xs) = [zs | ys <- subset xs, zs <- [ys,(x:ys)]]

输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

当我手动评估时,总结如下

手动输出:[],[3],[2],[1,2]

我在这里遗漏了一些逻辑,请您帮助我理解上述递归概念以及将首先评估守卫语句的哪一部分,评估顺序?

【问题讨论】:

  • 提示:格式化大代码块,突出显示它,然后按 ctrl+k。仅有的。小块使用“`”。
  • 请尝试用英文表达最后一行是如何构造其结果的。我认为这将说明它是如何工作的。
  • 我忍不住指出这个可以满足您需求的单行 gem。它使用来自Control.MonadfilterMsubset = filterM (const [False,True])。如此一来,您将获得与 subset 相同的输出(尽管排列方式不同)——效率丝毫不减!
  • @Alec Data.List.subsequences。也只需要一次导入。
  • @Zeta 哦,当然。我喜欢这个特定的定义,因为 IMO 它带来了 Haskell 的一些优点——能够根据高度多态的库函数简洁地定义相对复杂的操作。绝对没有样板。

标签: haskell recursion


【解决方案1】:

最后一行表示x:xs 的子集集是xs 的子集集以及添加到每个集的x

另一种说法是

zs <- [ys,(x:ys)]

为每个ys 生成两个集合,ysx:ys,这是xs 的子集之一。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多