【发布时间】:2015-06-17 16:48:17
【问题描述】:
我有一个任务,我被困在一个点上,我没有任何进展。 给定的是一个函数:
transpose :: [[a]] -> [[a]]
transpose [] = []
transpose ([]:ls) = transpose ls
transpose ll = [h | (h:_) <- ll] : transpose [t |(_:t) <- ll]
我将一方面使用 do-notation 和另一方面使用 bind-operator 再次编写它。我可以使用 hd、tl 和 (:)。 我对 do-notation 解决方案没有问题,但绑定版本存在模式匹配问题。 这是我目前所拥有的:
transheadA ll = ll >>= \(h:_) ->
return h
transtailA ll = ll >>= \(_:t) ->
return t
transposeA :: [[a]] -> [[a]]
transposeA [] = []
transposeA ([]:ls) = transposeA ls
transposeA ll = (transheadA ll : transposeA (transtailA ll))
do-notation 的相同样式有效,但使用绑定运算符时,我在 transheadA 处遇到模式匹配错误
\(h:_) -> ...
见:
transposeA [[1,2,3],[4,5,6],[7,8]]
[[1,4,7],[2,5,8],[3,6*** Exception: transpose.hs:(16,22)-(17,24): Non-exhaustive patterns in lambda
我一直在思考如何解决这个问题,但我不知道在哪里添加一个新模式来让这个工作。
编辑
当然,我只是想要提示。 直接解决方案既不是家庭作业的意义,也不是本板的意义。 谢谢你
编辑解决方案
感谢 CommuSoft,我想我可以解决这个问题。 我现在的解决方案如下:
transheadA :: [[a]] -> [a]
transheadA ll = ll >>= f
where f (h:_) = return h
f _ = fail []
transtailA :: [[a]] -> [[a]]
transtailA ll = ll >>= f
where f (_:t) = return t
f _ = fail []
transposeA :: [[a]] -> [[a]]
transposeA [] = []
transposeA ([]:ls) = transposeA ls
transposeA ll = (transheadA ll : transposeA (transtailA ll))
【问题讨论】:
-
当一个参数比其他参数短时,预期的行为是什么?您是否打算输入为
[[1,2,3], [4,5,6], [7,8,9]]?或者可能只是一个错字? -
问题是不能确定列表中的所有元素都有一个头部,例如空数组
[]没有。<-不仅仅是匹配,它还过滤。 -
输入正确。比其他列表短的列表将被排除在外,根本不考虑结果。最好说,当没有更多元素进入结果列表列表时,应该附加空列表,或者更好的是,什么都不做。
标签: haskell pattern-matching bind