Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell pattern matching gone wrong

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?

like image 247
Andrea Fiore Avatar asked Nov 30 '25 11:11

Andrea Fiore


1 Answers

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).

like image 107
sepp2k Avatar answered Dec 03 '25 15:12

sepp2k



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!