列表附加在 Haskell

List appending in Haskell

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

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 [] = []

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

with foo [] = [] 最后一个 b <- foo xsxs == [] 时将无法得到任何东西,因为它想从无到有地拉出一个 b - 所以列表-领悟会空虚

foo [] = [[]] 最终将是 b <- [[]] 所以 b 将得到一个 [].

备注

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

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

我认为这也更容易 read/explain:从 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] ]