Если это нормально для элементов в возвращаемом списке находиться в различных относительных положениях, чем они были в первоначальном списке, то вы можете легко (и с более высокой производительностью) решить эту проблему с комбинацией сортировки, группировка и CONCAT «ING:
testfunc list c = concat $ filter (\p -> length p /= c) $ group (sort list)
Если вы хотите сделать это ваш путь, вы могли бы использовать drop
пропустить первый элемент в списке (это не так, см редактировать):
testfunc list c
| list == [] = []
| (length(filter (==(head list)) list) == c) = testfunc (filter (/=(head list)) list) c
| otherwise = testfunc (drop 1 list) c
Я нота вполне уверен, что я понял вашу проблему, так это то, что вам нужно?
EDIT: Теперь я понимаю вашу проблему, ваша функция не работает должным образом после первого элемента. Если сохранение порядка важно, вы могли бы попробовать что-то вроде:
testfunc list c = filter (\s -> s `elem` validStrings) list
where validStrings = map head $ filter (\p -> length p /= c) $ group (sort list)
не специфичны к этому вопросу: я вижу много вопросов, связанных охранников в последнее время, что приводит к использованию частичных функций и избежать сопоставления с образцом. Интересно, слишком ли в курсе/учебнике/книге уделяется слишком много внимания охранникам, а также программистам-программистам в отношении плохого кода. Преподавателям: рассмотрите вопрос о запрете использования частичных функций (или просто притвориться, что они не существуют в курсе), при обучении Haskell они приносят больше вреда, чем пользы, ИМХО). – chi
@chi, возможно, это связано с вопросами об объятиях ... ^^ – Carsten