***例外:Prelude.head清空列表。什么是基本情况?

时间:2015-10-05 08:18:07

标签: haskell

我正在编写一个获取2矩阵乘积的函数。

transpose' :: [[a]] -> [[a]]
transpose' [[]] = []
transpose' m = (map head m) : transpose' (map tail m)

dotProduct :: [Int] -> [Int] -> Int
dotProduct [] [] = 0
dotProduct (x:xs) (y:ys) = (x*y) + dotProduct xs ys

matrixProduct :: [[Int]] -> [[Int]] -> [[Int]]
matrixProduct [] _ = []
matrixProduct (x:xs) y = (map (dotProduct x) (transpose' y)):matrixProduct xs y

我总是得到类似[[2,2, ***Exception: Prelude.head empty List

的内容

是因为我的函数有错误的基本情况吗?

我不确定应该是什么。

1 个答案:

答案 0 :(得分:3)

我修复了我在解决方案中发现的问题,这就是我得到的:

transpose :: [[a]] -> [[a]]
transpose [] = repeat []
transpose (m:ms) = zipWith (:) m (transpose ms)

dotProduct :: [Int] -> [Int] -> Int
dotProduct xs ys = sum $ zipWith (*) xs ys

matrixProduct :: [[Int]] -> [[Int]] -> [[Int]]
matrixProduct xs ys = [ [dotProduct x y | y <- transpose ys ] | x <- xs ]

你可以看到这应该非常接近矩阵乘法的row * col定义(表示中矩阵的行只是外部列表的元素,列是元素的转置矩阵外部列表)

除此之外,我简化了你的dotProduct(但你的很好)和 修复了你的transpose' - 顺便说一下,这是你错误的来源!

我认为基本的想法是正确的,但你遇到了基本情况([]而不是[[]])以及你应该将第一行映射到转置休息的方式的问题 - 同时注意您可以使用repeat [][]提供zipWith的无限列表,因为[]会很好地处理它 - 如果您使用zipWith (:) m [] == []而不是您的递归案例会在[]并冒泡到transpose

我的m与您的head有点不同而且可能很复杂 - 您的问题是tail内的一个或多个列表可能为空,这会导致transpose' :: [[a]] -> [[a]] transpose' m | and (map (not . null) m) = (map head m) : transpose' (map tail m) | otherwise = [] 和{{ 1}}失败 - 所以你必须保护这个案子:

map (not . null) m
  • result: [bool]会检查每一行是否为非空(and (map (not . null) m)
  • df['values'].apply(lambda x: pd.Series(x))断言所有行都是非空的