EDIT FOR CLARITY: I know what the ‘head of empty list’ error is and why it is thrown. What I don’t know is why there is no error when I use ‘elem’ but there is if I use ‘mElem’. That’s the only change I make to cause the error.
If I use the ‘Prelude.elem’ function the program runs but with one small error. I wrote my version of ‘elem’ (mElem) to counter this error. I looked at the source code for ‘elem’ and wrote my function in a similar style. However, the program crashes due to a ‘head of empty list error’ resulting from the function ‘getExisting’
genTupleCount :: [F.Record] -> [(String, Int)] -> [(String, Int)]
genTupleCount [] tuples = tuples
genTupleCount (x:xs) tuples | mElem (F.club x) (map fst tuples) = genTupleCount xs $ getNewTuples tuples existing
| otherwise = genTupleCount xs $ (F.club x, 1):tuples
where
existing = getExisting x tuples
getExisting :: F.Record -> [(String, Int)] -> (String, Int)
getExisting x tuples = head $ filter ((==F.club x).fst) tuples
getNewTuples :: [(String, Int)] -> (String, Int) -> [(String, Int)]
getNewTuples old e = (fst e, 1 + (snd e)):(delete e old)
mElem :: String -> [String] -> Bool
mElem _ [] = False
mElem str (x:xs) = (map toLower str) == (map toLower x) || mElem str xs
As Matt Fenwick said, you’re assuming there is an element that satisfies your condition. I suggest using
findinstead:This handles the case of there not being any such element by returning
Nothing, and let’s you skipmElementirely; just check the result ofgetExistingto find out whether there is any such element, and if there is, what its value is.As to why using
mEleminstead ofelemcauses your program to crash, it is because it does not verify that there is an element that satisfies the conditiongetExistingsearches for.getExistingdoesn’t normalise the capitalisation asmElemdoes, so ifnElemreturns True only because of its case-folding, then the call togetExistingwill occur, and it will performheadon the empty list, becausefilterwill find no elements matchinggetExisting‘s stricter condition.The
findsolution avoids this potential for error, since it only has the condition in one place.