如何处理Haskell中列表的递归(转置操作)
How to deal with recursing through a list in Haskell (transpose operation)
虽然我知道 Haskell 中可能有转置或 ZipList 函数,但我正在尝试构建我自己的转置函数,它将采用 n 个等长列表m 并将它们转置为长度为 n.
的 m 列表
到目前为止,我的函数几乎可以使用以下代码:
list = [[1,2,3],[4,5,6],[7,8,9]]
head' (x:xs) = x
head'' [] = []
head'' (xs:lxs) = head' xs:head'' lxs
tail' [] = []
tail' (x:xs) = xs
tail'' [] = []
tail'' (xs:lxs) = tail' xs:tail'' lxs
merge (xs:lxs) = (head' xs:head'' lxs):(merge (tail' xs:tail'' lxs))
当我在 ghci 中 运行 > merge list
时得到以下输出:
[[1,4,7],[2,5,8],[3,6,9],[*** Exception: list2.hs:16:1-16: Non-exhaustive patterns in function head'
我很确定这意味着我的 head'
函数中的空列表的基本情况丢失了。该列表已转置,只是没有关闭。在这种情况下我该如何处理这个问题?我有一个暗示,它可能与 Maybe
有关,但我无法以这种方式实现它。
您需要添加退出条件:
merge [] = []
merge ([]:xss) = merge xss
除了现有的 head
和 tail
函数外,map
就是您所需要的。为简单起见,这假设输入始终是一个非空列表(即 xs
可能是 [[],[],[]]
,但绝不会单独 []
,因此使用 [=12= 没有问题] 或 tail
.)
> map head list
[1,4,7]
> map tail list
[[2,3],[5,6],[8,9]]
> let foo xs = if null (head xs) then [] else map head xs : foo (map tail xs)
> foo list
[[1,4,7],[2,5,8],[3,6,9]]
虽然我知道 Haskell 中可能有转置或 ZipList 函数,但我正在尝试构建我自己的转置函数,它将采用 n 个等长列表m 并将它们转置为长度为 n.
的 m 列表到目前为止,我的函数几乎可以使用以下代码:
list = [[1,2,3],[4,5,6],[7,8,9]]
head' (x:xs) = x
head'' [] = []
head'' (xs:lxs) = head' xs:head'' lxs
tail' [] = []
tail' (x:xs) = xs
tail'' [] = []
tail'' (xs:lxs) = tail' xs:tail'' lxs
merge (xs:lxs) = (head' xs:head'' lxs):(merge (tail' xs:tail'' lxs))
当我在 ghci 中 运行 > merge list
时得到以下输出:
[[1,4,7],[2,5,8],[3,6,9],[*** Exception: list2.hs:16:1-16: Non-exhaustive patterns in function head'
我很确定这意味着我的 head'
函数中的空列表的基本情况丢失了。该列表已转置,只是没有关闭。在这种情况下我该如何处理这个问题?我有一个暗示,它可能与 Maybe
有关,但我无法以这种方式实现它。
您需要添加退出条件:
merge [] = []
merge ([]:xss) = merge xss
head
和 tail
函数外,map
就是您所需要的。为简单起见,这假设输入始终是一个非空列表(即 xs
可能是 [[],[],[]]
,但绝不会单独 []
,因此使用 [=12= 没有问题] 或 tail
.)
> map head list
[1,4,7]
> map tail list
[[2,3],[5,6],[8,9]]
> let foo xs = if null (head xs) then [] else map head xs : foo (map tail xs)
> foo list
[[1,4,7],[2,5,8],[3,6,9]]