列表附加在 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 xs
在 xs == []
时将无法得到任何东西,因为它想从无到有地拉出一个 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] ]
所以我写了一个函数,它将列表列表作为参数,并从第一个列表中获取每个元素,并将其附加到列表尾部的递归调用函数,结果返回所有可能的组合从这些列表中选择元素。
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 xs
在 xs == []
时将无法得到任何东西,因为它想从无到有地拉出一个 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] ]