【发布时间】:2019-01-04 09:08:41
【问题描述】:
虽然我知道 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 有关,但我无法以这种方式实现它。
【问题讨论】:
-
head' (x:xs) = x,但head' []是什么? -
由于
head' xs:head'' lxs = head'' (xs:lxs),您可以将merge (xs:lxs) = (head' xs:head'' lxs):...折叠成merge (xs:lxs) = (head'' (xs:lxs)):...。类似的等式推理适用于...,给出merge (xs:lxs) = (head'' (xs:lxs)):(tail'' (xs:lxs))。在这一点上,模式匹配没有多大意义。merge lxs = head'' lxs:tail'' lxs。但是现在你绝对应该怀疑:merge的这个定义显然总是调用(:)而从不调用[]。那么如何到达merge输出的“结尾”呢?
标签: list haskell recursion transpose non-exhaustive-patterns