I'm just wondering about a recursion function I'm laying out in Haskell. Is it generally better to use guards than patterns for recursion functions?
I'm just not sure on what the best layout is but I do know that patterns are better when defining functions such as this:
units :: Int -> String
units 0 = "zero"
units 1 = "one"
is much preferred to
units n
| n == 0 = "zero"
| n == 1 = "one"
I'm just not sure though when it comes to recursion as to whether this is the same or different.
Just not quite sure on terminology: I'm using something like this:
f y [] = []
f y (x:xs)
| y == 0 = ......
| otherwise = ......
or would this be better?
f y [] = []
f 0 (x:xs) =
f y (x:xs) =
My general rule of thumb would be this:
==
check.With recursion, you usually are checking for a base case. So if your base case is a simple ==
check, then use pattern matching.
So I'd generally do this:
map f [] = []
map f (x:xs) = f x : map f xs
Instead of this (null
simply checks if a list is empty. It's basically == []
):
map f xs | null xs = []
| otherwise = f (head xs) : map f (tail xs)
Pattern matching is meant to make your life easier, imho, so in the end you should do what makes sense to you. If you work with a group, then do what makes sense to the group.
[update]
For your particular case, I'd do something like this:
f _ [] = []
f 0 _ = ...
f y (x:xs) = ...
Pattern matches, like guards, fall from top to bottom, stopping at the first definition that matches the input. I used the underscore symbol to indicate that for the first pattern match, I didn't care what the y
argument was, and for the second pattern match, I didn't care what the list argument was (although, if you do use the list in that computation, then you should not use the underscore). Since it's still fairly simple ==
-like checks, I'd personally stick with pattern matching.
But I think it's a matter of personal preference; your code is perfectly readable and correct as it is. If I'm not mistaken, when the code is compiled, both guards and pattern matches get turned into case statements in the end.