crislanio_macedo Posted March 11, 2015 at 12:44 PM Report Share #579145 Posted March 11, 2015 at 12:44 PM (edited) Olá pessoal, aconteceu um caso que chega até engraçado, vejamos as funções abaixo. concatena3 = foldl (\a b@(y:ys)->a++b) [] -- por que aceita e dá erro no final concatena2 = foldl (\x xs->x++xs ) [] concatena4 = foldl1 (\a@(x:xs) b@(y:ys)->a++b) -- aceita e não erro no final Agora queria que os srs, me dessem uma explicação do por que o erro na função concatena3 ao querer usar \a@(x:xs) *Main> concatena2 [[1,2] ,[2,3]] [1,2,2,3] *Main> concatena4 [[1,2] ,[2,3]] [1,2,2,3] *Main> concatena3 [[1,2] ,[2,3]] [1,2,2,3] --------------------------------- *Main> concatena3 [[1,2] ,[2,3]] *** Exception: Exercicios-2Entrega.hs:256:21-44: Non-exhaustive patterns in lambda concatena3 = foldl (\a@(x:xs) b@(y:ys)->a++b) [] -- por que aceita e dá erro no final O erro como podem ver na concatena3 acontece, mas não tenho explicação do porque isso acontece. Edited March 11, 2015 at 12:50 PM by crislanio_macedo Link to comment Share on other sites More sharing options...
pwseo Posted March 11, 2015 at 03:13 PM Report Share #579156 Posted March 11, 2015 at 03:13 PM crislanio_macedo, Pelo que percebi, a tua função concatena3 deixa de funcionar quando substituis o argumento a por a@(x:xs) (o teu post estava um pouco confuso -- deverias ter colocado a redefinição da função entre os dois exemplos e não no final dos mesmos). Passando ao problema propriamente dito, a questão é relativamente simples e deve-se a um erro que já cometeste noutro tópico e para o qual já foste avisado (irás perceber de seguida). Antes de começarmos, podemos pegar na tua função anónima e torná-la numa função «normal» para perceberes melhor: -- Este código é em tudo equivalente ao teu, apenas mais compreensível concatena3 = foldl f [] -- este [] é o elemento inicial where f a@(x:xs) b@(y:ys) = a ++ b Quando a função foldl invoca a tua função anónima pela primeira vez, passa-lhe como argumentos o elemento inicial (que no teu caso é []) e o primeiro elemento da lista a processar (que é [1,2]). O problema surge na definição dos argumentos formais da função: tu disseste ao compilador que o primeiro argumento (de nome a) é uma lista com pelo menos um elemento ((x:xs)) e nesta primeira invocação esse argumento é nada mais nada menos do que uma lista vazia, []. O compilador queixa-se porque [] é incompatível com (x:xs), mas o erro que emite diz algo diferente: diz que não definiste padrões exaustivos -- é uma forma de dizer que não previste todos os casos possíveis, aqui especificamente o caso do primeiro argumento ser uma lista vazia. Se tivesses deixado apenas o a a identificar o primeiro argumento, tudo estaria bem porque seria compatível com todos os tipos de listas (vazias ou não). E agora voltamos ao que eu referi no início: já te avisámos noutro tópico para a inclusão de código desnecessário, e embora das outras vezes fosse completamente redundante, neste caso acabou mesmo por te criar um erro em tempo de execução, o que é grave. Regra geral, quanto mais simples, melhor. E já agora, podemos simplificar a tua função muito mais: concatena3 = foldl (\a@(x:xs) b@(y:ys) -> a ++ b) [] = -- os (x:xs) e (y:ys) eram inúteis (e até errados, como vimos) = foldl (\a b -> a ++ b) [] = -- se f a b = a ++ b, então f = (++) = foldl (++) [] Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now