I am learning some Haskell, and I am trying to get my head around how pattern matching works.
In doing so, I have written a simple nth function.
nth' :: Integer -> [a] -> a
nth' n [] = error "Index out of bound"
nth' n (x:xs) = if n == 0 then x else nth' (n - 1) xs
This first implementation seem to work as expected.
-- nth' 25 ['a'..'z']
-- 'z'
-- nth' 26 ['a'..'z']
-- *** Exception: Index out of bound
However, when I refactor it replacing the if statement with pattern matching, I end up getting the "Index out of bound" exception where I clearly should not.
nth' :: Integer -> [a] -> a
nth' _ [] = error "Index out of bound"
nth' 0 (x:[]) = x
nth' n (_:xs) = nth' (n - 1) xs
-- nth' 2 ['a'..'z']
-- *** Exception: Index out of bound
What am I doing wrong?
The pattern x:[] matches a list that contains exactly one element. So your nth' 0 (x:[]) case will be executed only if the first argument is 0 and the second argument is a one-element list. If the second argument is a list with more than one argument, it'll go into the last case.
You need to change the second case to nth' 0 (x:_) = x, so that it matches no matter how many elements are in the list (as long as it's at least one).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With