【发布时间】: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.Monad的filterM。subset = filterM (const [False,True])。如此一来,您将获得与subset相同的输出(尽管排列方式不同)——效率丝毫不减! -
@Alec
Data.List.subsequences。也只需要一次导入。 -
@Zeta 哦,当然。我喜欢这个特定的定义,因为 IMO 它带来了 Haskell 的一些优点——能够根据高度多态的库函数简洁地定义相对复杂的操作。绝对没有样板。