编译器告诉我这个函数有非详尽的模式,但是每个场景都被覆盖了,不是吗?
allNeighbors :: Ord v => Graph v -> [v] -> [v] -> [v]
allNeighbors graph (x:xs) neighborsList
| length (x:xs) <= 0 = neighborsList
| length (x:xs) == 1 = neighborsList ++ (neighbors x graph)
| length (x:xs) > 1 = allNeighbors graph xs (neighborsList ++ (neighbors x graph))
答案 0 :(得分:4)
未涵盖:allNeighbors a [] b
。 (试试吧;你应该收到错误。)
length (x:xs) <= 0
案例无法访问(第一个元素为x
的列表长度不能为0)。
length (x:xs) == 1
最好写成[x]
形式的模式。
length (x:xs) > 1
不必要地效率低下:它强制程序遍历整个列表来计算长度,只是为了查看是否有多个元素。这可以由x : xs@(_ : _)
等模式替换。
事实上,整个功能可以这样重写:
allNeighbors :: Ord v => Graph v -> [v] -> [v] -> [v]
allNeighbors graph list neighborsList =
case list of
[] -> neighborsList
[x] -> neighborsList ++ neighbors x graph
x : xs -> allNeighbors graph xs (neighborsList ++ neighbors x graph)