Among the myriad ways you could write this, two possibilities would be
binListToDec xs = if length xs == 0 then 0 -- see below
else (head xs) + binListToDec (tail xs)
and
binListToDec [] = 0
binListToDec (x:xs) = x + binListToDec xs
You appear to be trying to combine bits of each. There's no way to write a single pattern that matches simultaneously 1) an empty list and 2) a non-empty list with 3) its head and tail matched separately.
xs matches 1) and 2).
all@(x:xs) matches 2) and 3)
1) and 3) cannot be matched, because the pairing is nonsensical: an empty list doesn't have a separate head and tail. [] and (x:xs) match lists from two non-overlapping sets of possible list values.
Update: there is a lazy pattern match all@(~(x:xs)). The tilde prevents the match (x:xs) from being attempted until there is a need to
evaluate x or xs. We think of
binListToDec all@(~(x:xs)) = if length all == 0 then 0 else x + binListToDec
as equivalent to
binListToDec all = if length all == 0
then 0
else let (x:xs) = all
in x + binListToDec
A lazy pattern match can still fail, but here we defer using x and xs until we know it won't.
length binListToDec attempts to compute the length of the function itself, not the length of its argument, in your attempt. The correct argument for length is used above. Also, the generally accepted sum of an empty list is 0, not 1.
length binListToDecsupposed to do?(x:xs)and (b) the length can never be zero, since(x:xs)is the pattern for a non-empty list.