Как закодировать удаление функции без модуля prelude в Haskell?

#haskell #recursion

#haskell #рекурсия

Вопрос:

Я хочу сам написать несколько функций prelude Haskell , чтобы лучше понять это и немного потренироваться с этим. Я уже закодировал TAKE функцию, но у меня есть некоторые проблемы с DROP функцией.

 take1 :: Int -> [a] -> [a]

take1 _ [] = []

take1 0 _ = []

take1 n (x:xs) = x:take1 (n-1) xs 

-- Input: take 5 [1,2,3,4,5,6,7] 

-- Output: [1,2,3,4,5]

--This is the take Function and its working.

drop1 :: Int -> [a] -> [a]

drop1 _ [] = []

drop1 n (x:xs) = x : drop1 (n 1) xs 

-- Input: drop 5 [1,2,3,4,5,6,7,8,9,10] 

-- Output: [6,7,8,9,10] 

-- It´s printing out the whole List and not the wanted result.
  

Комментарии:

1. Боюсь, вам придется пересмотреть свою логику здесь. Во-первых, вы автоматически включаете первый элемент списка ( x ) , который вы, очевидно, не хотите делать (если n он не равен нулю).

Ответ №1:

Идея drop состоит в том, чтобы пропустить n первые элементы, поэтому просто отбрасывайте их рекурсивно, пока не достигнете 0:

 drop:: Int -> [a] -> [a]
drop _ []     = []
drop 0 xs     = xs
drop n (_:xs) = drop (n-1) xs
  

Важный базовый вариант, который вы упускаете drop 0 xs = xs , таков: если мне нечего отбрасывать, я просто возвращаю то, что получил.
Также обратите внимание, что мы уменьшаем ( (n-1) ), а не увеличиваем в рекурсивном вызове, иначе вы никогда не дойдете до базового варианта.

Комментарии:

1. Я бы также подчеркнул тот факт, что вы заменили n 1 на n - 1 .