我得到了这段代码来制作转置矩阵,但是并不能100%正常工作。
type Mat a = [[a]]
transpose' :: Eq a => Mat a -> Mat a
transpose' [] = []
transpose' (h:t) = primelem (h:t):transpose' (eliminate' (h:t))
primelem :: Mat a -> [a]
primelem [] = []
primelem [[x]] = [x]
primelem ((x:xs):t) = x : primelem t
eliminate' :: Eq a => Mat a -> Mat a
eliminate' [] = []
eliminate' (h:t) = (delete (head h) h):eliminate' t
*Main> transpose' [[1,2,3],[0,4,5],[0,06]]
[[1,0,0],[2,4,6],[3,5*** Exception:(..)Non-exhaustive patterns in function primelem
我正在设法弄清楚,但我真的不知道缺少哪种情况。
答案 0 :(得分:5)
要发现丢失的情况,应使用-Wall
标志打开警告,如下面的GHCi会话所示。
> :set -Wall
> type Mat a = [[a]]
> :{
| primelem :: Mat a -> [a]
| primelem [] = []
| primelem [[x]] = [x]
| primelem ((x:xs):t) = x : primelem t
| :}
<interactive>:5:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘primelem’: Patterns not matched: ([]:_)
<interactive>:7:14: warning: [-Wunused-matches]
Defined but not used: ‘xs’
因此,您失踪的情况是:
primelem ([]:t) = ...
答案 1 :(得分:2)
您对此太想了。空列表的列表是它自己的转置。
transpose m | all null m = []
| any null m = error "Not a matrix"
否则,将每个列表的第一个元素作为转置的第一行,并将其余矩阵转置为转置的其余部分。
transpose m = map head m : transpose (map tail m)
此功能实际上是合计的,仅在那些实际上不是矩阵的列表中失败。它在非矩阵值上失败较晚的事实有点夸张:
> transpose [[1,2], [3]]
[[1,3]*** Exception: Not a matrix
CallStack (from HasCallStack):
error, called at tmp.hs:3:28 in main:Main
如果您想更干净地处理无效矩阵,请返回Maybe (Mat a)
。
transpose :: Mat a -> Maybe (Mat a)
transpose m | all null m = Just []
| any null m = Nothing
| otherwise = ((map head m):) <$> transpose (map tail m)