2

I am using the following function:

combinations :: Int -> [a] -> [[a]]
combinations k xs = combinations' (length xs) k xs
  where combinations' n k' l@(y:ys)
          | k' == 0   = [[]]
          | k' >= n   = [l]
          | null l    = []
          | otherwise = Prelude.map (y :) (combinations' (n - 1) (k' - 1) ys) ++ combinations' (n - 1) k' ys 

It works just fine for just about any example i can come up with, but when i call it from other functions in my larger project, for some cases I get an exception:

Exception: projekt.hs:(34,9)-(38,108): Non-exhaustive patterns in function combinations'

Is there something wrong with the above definition? Is it missing some case? I thought otherwise handles anything that doesn't fall into previous cases.

Mihai Maruseac
  • 20,967
  • 7
  • 57
  • 109
Marcin
  • 380
  • 3
  • 20
  • 3
    `otherwise` handles anything that doesn't fall into previous _guards_ -- but doesn't make a pattern match support other _cases_. – Daniel Wagner May 27 '15 at 19:15
  • 2
    you could fix this with a very small edit, by changing `l@(y:ys)` to `l@ ~(y:ys)`, making the pattern lazy, and so irrefutable (so empty lists are accepted too). I would recommend against such a style though, it makes the code too fragile and non-apparent. – Will Ness May 27 '15 at 21:33

1 Answers1

8

Because of l@(x:xs) in combinations' n k' l@(y:ys) you're missing the case combinations _ _ [].

The guard null l will always be False.

Mihai Maruseac
  • 20,967
  • 7
  • 57
  • 109