***例外:Prelude.head空列表。什么是基本情况? [英] ***Exception: Prelude.head empty List. What is the base case?
问题描述
转置':: [[a]] - > [[a]]
转置'[[]] = []
转置'm =(地图头m):转置'(地图尾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)(转置'y)):matrixProduct xs y
我总是得到类似于 [[2,2,*** Exception:Prelude.head empty List
是因为我的函数有错误的基本情况吗?
I我不知道该怎么做。
我解决了在解决方案中发现的问题,这就是我会得到的:
转置:: [[a]] - > [[a]]
转置[] = repeat []
转置(m:ms)= zipWith(:) m(转置ms)
dotProduct :: [Int] - > [Int] - > Int
dotProduct xs ys = sum $ zipWith(*)xs ys
matrixProduct :: [[Int]] - > [[Int]] - > [[Int]]
matrixProduct xs ys = [[dotProduct x y | y< - 转置ys] | x < - xs]
如你所见,这应该非常接近 row * col
矩阵乘法的定义(表示矩阵的行只是外部列表的元素,列是转置矩阵外部列表的元素)
除此之外,我简化了一下 dotProduct
(但你的很好)和
修正了你的转置'
- 顺便说一句,是你错误的根源!
我认为基本的想法是正确的,但你遇到基础案例( []
not [[]]
)和您应该映射的方式转换休息的第一行 - 也请注意,您可以使用 repeat []
,这会给你一个无限的 []
作为 zipWith
会处理它就好 - 如果你使用 []
,那么你的递归情况会在 zipWith(:) m [] == []
并冒泡只是 []
我的转置
与你的有些不同,也许会变得复杂 - 你的问题是 m
中的一个或多个列表可能是空的,这将导致头部
和尾部
失败 - 所以您必须防范这种情况:
转置':: [[a]] - > [[a]]
转置'm
|和(map(not null)m)=(map head m):transpose'(map tail m)
|否则= []
-
map(not。 null)m
会检查每一行是否为非空(result:[bool]
) -
和(map(not。null)m)
断言所有行都是非空的
I am writing a function of getting the product of 2 matrix.
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
I always get something like
[[2,2, ***Exception: Prelude.head empty List
Is it because I have wrong base case for the function?
I am not sure what that should be.
解决方案I fixed the issues I found in your solution and this is what I would get:
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 ]
as you can see this should be really close to the
row * col
definition of matrix-multiplication (the rows of a matrix in your representation are just the elements of the outer-list and the columns are the elements of the transposed matrix outer-list)Aside from this I simplified your
dotProduct
a bit (but yours was fine) and fixed yourtranspose'
- which by the way was the source of your error!I think the basic idea was right but you got into trouble with the base case (which is
[]
not[[]]
) and the way you should map the first row to the transposed rest - also note that you can userepeat []
which will give you an infinite list of[]
aszipWith
will deal with it just fine - if you use[]
instead your recursive case will break atzipWith (:) m [] == []
and bubble up to just[]
my
transpose
is a bit different to yours and maybe to complicated - the problem with yours is that one or more list insidem
could be empty which will causehead
andtail
to fail - so you have to guard this case:transpose' :: [[a]] -> [[a]] transpose' m | and (map (not . null) m) = (map head m) : transpose' (map tail m) | otherwise = []
map (not . null) m
will check each row if it is non-empty (result: [bool]
)and (map (not . null) m)
asserts that all rows are non-empty
这篇关于***例外:Prelude.head空列表。什么是基本情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!