1

Why is the following not allowed?

revList :: [Integer] -> [Integer]
revList [] = []
revList = go []
    where 
        go acc [] = acc
        go acc (x:xs) = go (x:acc) xs

I get that removing the second line lets is compile, but I'd like to understand why. The type for revList is the same for both definitions, no? Also, I thought I could put has many patterns as I like, and the first match will be chosen. So I don't quite understand what is the problem here.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
Chechy Levas
  • 2,206
  • 1
  • 13
  • 28
  • 4
    it's just a requirement for each function to have the same number of arguments specified in every clause of its definition. someone will probably explain why, but you can just treat is as a compiler requirement. you can change the second clause to `revList xs = go [] xs ...` and it will compile. – Will Ness May 22 '19 at 16:31
  • 1
    Or you could remove the first clause entirely. It isn't necessary. – Carl May 22 '19 at 16:33
  • @Carl I said as much in the question. – Chechy Levas May 22 '19 at 16:34
  • I always figured this was a requirement because mismatched numbers of arguments are nearly always a sign of missing parentheses or another easy-to-miss syntactic oversight. Of course in those cases it would most likely fail with a type mismatch or something, but it might be more difficult to trace the source of that kind of error. – DarthFennec May 22 '19 at 16:37
  • 2
    "Also, I thought I could put has many patterns as I like, and the first match will be chosen." You're correct. If there's a runtime error on your second pattern, but a call to the function matches the first pattern, you won't get an error. But this is a compile-time error, and all compile-time errors are presented during compilation. This is actually great, because it means you don't need to test every code path to catch most errors, like you do in Python or Javascript. – DarthFennec May 22 '19 at 16:46

0 Answers0