Haskell矩阵乘法程序出现‘空列表取tail’错误,请求调试帮助
修复Haskell矩阵乘法程序中的"Prelude.tail: empty list"错误
你的程序出现Prelude.tail: empty list错误,核心原因是多个函数的模式匹配未覆盖边界情况,且直接使用head/tail操作空列表。以下是具体问题排查和修复方案:
1. 向量点积函数multVecttt
原代码的模式匹配遗漏了「一个向量非空、另一个为空」的场景(比如multVecttt [2] []),会导致递归中调用head []或tail []。改用cons模式匹配更安全,同时覆盖所有边界:
multVecttt :: [Int] -> [Int] -> Int -- 向量点积 multVecttt [] _ = 0 multVecttt _ [] = 0 multVecttt (x:xs) (y:ys) = x * y + multVecttt xs ys
2. 矩阵转置相关函数transHead/transTail/trans
原代码处理空行或矩阵末尾时,直接调用tail操作空列表触发错误。重构这三个函数,用模式匹配避免空列表操作:
transHead(提取矩阵每行首元素)
transHead :: [[Int]] -> [Int] transHead [] = [] transHead ([]:_) = [] -- 遇到空行,转置终止 transHead ((x:_):xs) = x : transHead xs
transTail(提取矩阵每行的尾元素组成新矩阵)
transTail :: [[Int]] -> [[Int]] transTail [] = [] transTail ([]:xs) = transTail xs -- 跳过空行 transTail ((_:xs):xss) = xs : transTail xss
trans(矩阵转置)
用通用终止条件替代冗余的模式匹配,确保所有边界都被覆盖:
trans :: [[Int]] -> [[Int]] -- 矩阵转置 trans xss | all null xss = [] -- 所有行都为空时终止 | otherwise = transHead xss : trans (transTail xss)
3. 向量乘矩阵函数multVectMat
原代码模式匹配冗余,且使用head/tail增加出错风险,改用cons模式简化:
multVectMat :: [Int] -> [[Int]] -> [Int] -- 向量乘矩阵 multVectMat _ [] = [] multVectMat [] _ = [] multVectMat xs (y:ys) = multVecttt xs y : multVectMat xs ys
4. 矩阵乘矩阵函数multMatrix
原代码的错误模式匹配(比如[][[a]]=[[a]])不符合矩阵乘法逻辑,改用cons模式重构,同时依赖修复后的trans函数:
multMatrix :: [[Int]] -> [[Int]] -> [[Int]] -- 矩阵乘法 multMatrix [] _ = [] multMatrix _ [] = [] multMatrix (x:xs) yss = multVectMat x (trans yss) : multMatrix xs yss
修复后完整代码
multVecttt :: [Int] -> [Int] -> Int -- 向量点积 multVecttt [] _ = 0 multVecttt _ [] = 0 multVecttt (x:xs) (y:ys) = x * y + multVecttt xs ys multVectMat :: [Int] -> [[Int]] -> [Int] -- 向量乘矩阵 multVectMat _ [] = [] multVectMat [] _ = [] multVectMat xs (y:ys) = multVecttt xs y : multVectMat xs ys multMatrix :: [[Int]] -> [[Int]] -> [[Int]] -- 矩阵乘法 multMatrix [] _ = [] multMatrix _ [] = [] multMatrix (x:xs) yss = multVectMat x (trans yss) : multMatrix xs yss trans :: [[Int]] -> [[Int]] -- 矩阵转置 trans xss | all null xss = [] | otherwise = transHead xss : trans (transTail xss) transHead :: [[Int]] -> [Int] transHead [] = [] transHead ([]:_) = [] transHead ((x:_):xs) = x : transHead xs transTail :: [[Int]] -> [[Int]] transTail [] = [] transTail ([]:xs) = transTail xs transTail ((_:xs):xss) = xs : transTail xss
测试示例:比如multMatrix [[1,2],[3,4]] [[5,6],[7,8]]会返回[[19,22],[43,50]],符合预期。
内容的提问来源于stack exchange,提问作者mimi
相关产品推荐
相关产品推荐

