Неполные паттерны в функции take6 error?

Поэтому я создал эту функцию, чтобы дать мне "n" первых элементов из списка "(b:bs);

 1  module Sexta where  
 2
 3  take6::Int->[a]->[a]
 4  take6 n (b:bs) = if n<=0 then [] 
 5                 else [b] ++ (take6 (n-1) bs)

Проблема в том, что когда я пытаюсь: take6 2 [], это показывает:

*** Exception: sexta.hs:(4,1)-(6,15): Non-exhaustive patterns in function take6

Я не знаю почему, потому что когда я попробую это вручную:

   take6 2 []
   = [] ++take6 1 []
   = [] ++[]++take6 0 []
   = [] ++[]++[]
   = []

3 ответа

Решение

В своей программе вы пишете:

take6 n (b:bs) = ...

Но здесь вы, таким образом, используете шаблон (b:bs) который является "против" конструктор списка. Конструктор против b и хвост bs, Тип списка имеет два конструктора: "минусы", которые мы здесь уже обсуждали, и пустой список. [], Haskell жалуется, что не может найти предложение для шаблона пустого списка второго аргумента. Таким образом, ваша функция должна быть определена с помощью формы:

take6 n [] = ...
take6 n (b:bs) = ...

Теперь вопрос все еще, что делать здесь. Независимо от того, что мы берем в случае пустого списка, мы больше не можем генерировать какие-либо элементы, поэтому вы, вероятно, захотите вернуть пустой список, поэтому:

take6 _ [] = []

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

take6 n (b:bs) | n <= 0 = []

но есть также случай, когда n > 0, В таком случае мы хотим действительно подготовиться b к take6 (n-1) bs, Имейте в виду, однако, что более эффективный способ предварения - снова использовать конструктор "cons":

               | otherwise = b : take6 (n-1) bs

или полностью:

take6 :: Int -> [a] -> [a]
take6 _ [] = []
take6 n (b:bs) | n <= 0 = []
               | otherwise = b : take6 (n-1) bs

Вы уничтожаете список, прежде чем проверять n, поэтому даже если он равен 0, вы требуете, чтобы список был не пустым. Вы можете использовать охрану для обработки этого случая, но это не поможет в этом случае, когда список слишком короткий.

Шаблон b:bs не соответствует пустому списку. Вам нужен отдельный случай для обработки пустого списка.

Другие вопросы по тегам