Advertencia de declaración if redundante en haskell

So I'm following the tutorial Learn you a Haskell for Great Good! and so far I absolutely love Haskell. But in one of the functions mentioned in the tutorial I'm getting a warning that the if-statement is redundant.

Edit: Let me be clear, the intent of the function is to act exactly the same way the elem function works (the one that is provided with Haskell by default).

Here's the original function:

elem' :: (Eq a) => a -> [a] -> Bool  
elem' y ys = foldl (\acc x -> if x == y then True else acc) False ys

Originally there were two warnings, one was eta reduction, so I removed the ys from the beginning and end of the function name to arrive at:

elem' :: (Eq a) => a -> [a] -> Bool  
elem' y = foldl (\acc x -> if x == y then True else acc) False

Now I tried to reduce the function to the following and it results in an error:

elem' :: (Eq a) => a -> [a] -> Bool  
elem' y = foldl (\acc x -> x == y)

I think I'm just very new to Haskell and can't see the obvious solution. Can someone tell me what code change would keep the function working correctly and yet remove the compiler warning?

preguntado el 08 de noviembre de 11 a las 14:11

Compiler warnings or compiler errors? -

@MattFenwick Until the last typed in function, they are only warnings, but the last one is an error, and won't compile. -

Can you give a reproducible example? I've tried your very first function with ghc -Wall and don't get any warnings mentioned. -

@maksenov well, I'm writing it in eclipse using the eclipseFP plugin and I'm working on a windows system. Could that be why you don't get a warning? Plus, the warning is just eclipse underlining it with a yellow line, which I believe is more accurately described as a suggestion from "HLint" if I'm not mistaken. -

@Asaf HLint is basically taken as gospel amongst Haskellers. -

2 Respuestas

if x == y then True else acc es el mismo que x == y || acc.

respondido 08 nov., 11:18

Cambiar a foldr also lets it work on infinite lists. elem' y = foldr (\x acc -> x == y || acc) False. elem' 3 [1..] ==> True - Dan Burton

This is indeed the very suggestion that HLint produces; not sure why Eclipse would drop this info. - Dan Burton

Thank you for the correct answer, and yes, I don't know why Eclipse doesn't include it. I do know this though, EclipseFP does NOT come with HLint automatically, I had to run cabal install HLint (or something like that) to install it. So perhaps I misspoke when I said eclipse was grabbing the info from HLint. My apologies if this is the case. - Asaf

Typing your last definition into GHCi without a type annotation:

Prelude> let elem' y = foldl (\acc x -> x == y)
Prelude> :t elem'
elem' :: (Eq b) => b -> Bool -> [b] -> Bool

It doesn't match your declared type.

Olvidaste el False at the end! If you add it in:

Prelude> let elem' y = foldl (\acc x -> x == y) False  -- note the False at the end
Prelude> :t elem'
elem' :: (Eq b) => b -> [b] -> Bool

It has the right type!

respondido 08 nov., 11:18

That certainly explains why there is an error, but how would I remove the warning without causing this error, or any other? Edit: Looks like the right answer now, thank you - Asaf

@Asaf -- does this code elem' y = foldl (\acc x -> x == y) False cause warnings? - Matt Fenwick

unfortunately I can't check it at the moment, but I will when I get back to my computer, thank you for your help - Asaf

It has the right type, but does not behave like elem. elem' [3,1] 3 produce False; since the accumulator is ignored, this function is essentially the same as elem' y xs = last xs == y - Dan Burton

@DanBurton -- I interpreted the question as how do I get this to compile/give me no warnings? .... I didn't even consider it from the point of view of writing a meaningful function. Do you think I should edit my answer? I'm not really sure about this. - Matt Fenwick

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.