2015-11-23 2 views
1

Итак, у меня есть функция, которая берет список списков и берет начало каждого списка и добавляет его в другой список. У меня есть защитники, которые, как я думал, охватывали все проблемы, но это не так. 't, может ли кто-нибудь понять, почему это может дать мне исключение.Haskell: неисчерпывающий шаблон в функции

makeL :: (Eq a) => [[a]]->[a] -> [a] 
makeL (h:t) l 
    | length (concat (h:t)) == 0 = l 
    | length h == 0 && length t /= 0 = makeL t l 
    | length h /= 0 && length t == 0 = l++[head h] 
    | otherwise = makeL t (l++[head h]) 

Когда я играю с ним в прелюдии, я не могу воспроизвести ошибку. но когда я запускаю программу, если [[a]] равно [[],[],[],[],[]] тем это дает ошибку Я думаю

+1

Несвязанный: этот вид анти-шаблона, основанный на «защищенности», в последнее время довольно популярен на SO. Кто-то должен написать статью «охранники, считающиеся вредными» ... – chi

+1

Это не касается вашего вопроса вообще, но я не могу не предложить его: вам может понравиться 'concatMap (take 1)'. –

+1

Не могу не упомянуть, что когда вы соблазняетесь использовать 'length' в списке, вы обычно делаете ошибку. – dfeuer

ответ

4

makeL (h:t) l исключительно соответствует случаю, когда список списков есть голова и хвост, но это не соответствует пустому списку (который не имеет головы).

Как минимум, вам нужно добавить случай, который имеет дело с пустым списком:

makeL [] l = -- implementation goes here 
+0

В программе он не может получить '[]' он будет иметь [[], [], [], []]. Но я пробовал то, что вы предложили, и оно все еще дает ошибку –

+0

Какая ошибка дает? –

+2

«В программе он не может получить» [] «он будет иметь [[], [], [], []]». Вы можете это знать, но GHC этого не делает, поэтому он предупреждает вас о неисчерпаемом шаблоне. –

0

Я думаю, что это шаблон задания, но не с помощью подопечных:

makeL :: (Eq a) => [[a]]->[a] -> [a] 
makeL [] l    = l -- base case, empty list return l 
makeL ([]:xs) l   = makeL xs l --case the list inside the list is empty, continue with the rest of the list 
makeL ((x:xxs):xs) l = makeL xs l++[x] --if the list in the list have a head append to l and continue with the list 
Смежные вопросы