-2

The compiler is telling me that this function has Non-exhaustive patterns, but every scenarios are covered, aren't they?

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))
Phil
  • 305
  • 1
  • 3
  • 13

1 Answers1

4

Not covered: allNeighbors a [] b. (Try it; you should get an error.)


The length (x:xs) <= 0 case is unreachable (a list whose first element is x cannot have length 0).

length (x:xs) == 1 is better written as a pattern of the form [x].

length (x:xs) > 1 is unnecessarily inefficient: It forces the program to walk through the whole list to compute the length, just to see whether there is more than one element. This could be replaced by a pattern like x : xs@(_ : _).


In fact, the whole function could be rewritten like this:

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)
melpomene
  • 84,125
  • 8
  • 85
  • 148
  • but allNeighbors a [] b should be covered by : length (x:xs) <= 0? – Phil Feb 26 '18 at 02:25
  • @Phil No, because as I wrote in my answer, that case is unreachable. Your base pattern is `allNeighbors graph (x:xs) neighborsList`, and `(x:xs)` doesn't match empty lists. – melpomene Feb 26 '18 at 02:28
  • @Phil `(x:xs)` matches a non-empty list and binds its head to x and tail to xs. – bipll Feb 26 '18 at 02:33
  • I see so that was my error, thanks! – Phil Feb 26 '18 at 02:38
  • 1
    @Phil: usually I think it is a good idea to compile with `-Wall` or `-fwarn-incomplete-patterns` (the former produces more warnings than the latter). In that case the compiler will show you the patterns that are not covered yet by the functions you defined. – Willem Van Onsem Feb 26 '18 at 08:08