Search code examples
listhaskellfold

how does foldr workk in this situation?


i have this function that counts the number of occurences of n in a list:

count n = foldr (\x acc -> if n == x then acc+1 else acc) 0

now if i do

> count 2 [2,2,3,2,2]
> 4

what i don't understand is why i can't do the following instead which i find far more easier to read

count n [x:xs] = foldr (\x acc -> if n == x then acc+1 else acc) 0 [x:xs]

count takes two arguments, but why when defining the function i dont explicitily write out the second argument (the list argument) where does it go?


Solution

  • The [x:xs] pattern is short for [(x:xs)], which means a singleton list (a list with one element) that matches the (x:xs) pattern.

    The (x:xs) pattern is a non-empty list. Indeed, here x is the head (the first element), and xs the tail (the list with the remaining elements). The pattern for an empty list is []. If you thus would write:

    -- does not work with empty lists
    count n (x:xs) = foldr (\x acc -> if n == x then acc+1 else acc) 0 (x:xs)

    It means it will not "fire" for an empty list. You can however make use of a parameter:

    count n xs = foldr (\x acc -> if n == x then acc+1 else acc) 0 xs

    This is a variable that will match with any value, so both empty and non-empty lists.