Aprendendo Haskell: como implementar minha própria versão da função init
Pergunta
Como parte do aprendizado Haskell, estou tentando implementar minha própria versão de várias funções associadas a listas. Agora estou preso no iniciar função. A função init em Haskell retorna todos os elementos em uma lista que não seja o último elemento.
Aqui está o que eu fiz até agora.
init' :: [Int] -> [Int]
init' [] = error "This function cannot be applied to an empty list"
init' [x] = [x]
init' (x:xs) = x : init' xs
Solução
Seu problema é o seu caso base. Aqui:
init' [x] = [x]
Você está dizendo que, quando você entra em uma lista com um elemento, deseja devolver a mesma lista. Este não é o resultado desejado. Quando você tem uma lista com apenas um elemento, deseja retornar uma lista vazia (todos, exceto o último elemento para um único item, é uma lista vazia).
init' [x] = []
Em uma nota lateral, você provavelmente deve declarar como
init' :: [a] -> [a]
Usar 'a' como o tipo generaliza -o para listas de qualquer coisa, em vez de apenas ints. Dessa forma, você pode chamar o init 'em qualquer tipo de lista. Por exemplo, init '"abcde" te daria "ABCD"
Outras dicas
Sua segunda regra deve ser:
init' [x] = []
Quando uma lista tem apenas um elemento, é o último, então a lista sem o último elemento é apenas a lista vazia.
init' [x] = [x]
Isso não está correto. Se você remover o último elemento de uma lista de um elemento, não receberá a mesma lista, receberá uma lista vazia.
Aqui está minha versão, tente isso.
init' :: [a] -> [a]
init' [] = error("This is not right, empty list is not allowed here")
init' (x:[]) = [x]
init' (x:xs:[]) = [x]
init' (x:xs) = x: init' xs