【问题标题】:List appending in Haskell在 Haskell 中追加列表
【发布时间】:2015-05-22 13:16:13
【问题描述】:

所以我写了一个函数,它将列表列表作为参数,并从第一个列表中获取每个元素,并将其附加到列表尾部的递归调用函数中,结果返回所有可能的选择组合这些列表中的元素。

foo :: [[a]] -> [[a]]
foo [] = [[]]
foo (x:xs) = [[(x !! a)] ++ b | a <- [0..length(x)-1], b <- foo xs]

*Main> foo [[1, 2], [3, 4], [5, 6]]
[[1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6], [2, 3, 5], [2, 3, 6], [2, 4, 5], [2, 4, 6]]

它确实可以正常工作,但是每当我将函数的第二行更改为

foo [] = []

每当我在类型有效的参数上调用它时,它总是返回一个空列表。有什么大不了的?

【问题讨论】:

  • xs 为空时,您的b &lt;- foo xs 将无法获得任何东西(因为从无中提取b 永远不会得到b)- 这是大交易(在正确的情况下它会拉b &lt;- [[]] 所以b 将得到[]):D
  • 哦,当然。谢谢:)
  • 这可以作为你的答案吗?
  • 是的,我现在完全明白了。
  • 你能解释一下吗

标签: list haskell append list-comprehension


【解决方案1】:

对于foo [] = [],最后一个b &lt;- foo xsxs == [] 时将无法获得任何东西,因为它想从无到有拉出b - 所以列表理解将为空。

使用foo [] = [[]] 最终将是b &lt;- [[]],因此b 将得到一个[]。

备注

你可以稍微简化一下(这样你就不需要昂贵的(!!)):

foo :: [[a]] -> [[a]]
foo [] = [[]]
foo (xs:xss) = [ y : ys | y <- xs, ys <- foo xss]

我认为这也更容易阅读/解释:从 xs 中取出每个 x 并将其与 xss 的每个组合递归组合到一个新列表中

foo [] = [] 会出什么问题:

我们用一个简单的案例来测试一下:

foo [[1],[2]]
= [ y:ys | y  <- [1], ys <- foo [ [2] ] ]
= [ 1:ys | ys <- [ y':ys' | y' <- [2], ys' <- foo [] ] ]
= [ 1:ys | ys <- [ 2:ys'  | ys' <- [] ] ]
= [ 1:ys | ys <- [] ]
= []

而不是(使用foo [] = [[]]):

foo [[1],[2]]
= [ y:ys | y  <- [1], ys <- foo [ [2] ] ]
= [ 1:ys | ys <- [ y':ys' | y' <- [2], ys' <- foo [] ] ]
= [ 1:ys | ys <- [ 2:ys'  | ys' <- [[]] ] ]
= [ 1:ys | ys <- [ 2:[] ] ]
= [ 1:[2] ]
= [ [1,2] ]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-18
    • 2014-05-09
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    • 2012-08-30
    相关资源
    最近更新 更多