Pregunta

I'm learning Haskell and i've run into something i can't understand and i can't find an explanation. So, I was testing some functions over infinite lists to see how they worked, and i found a diference between map and filter that I'd like to understand.

Prelude.map definition:

map _ []     = []
map f (x:xs) = f x : map f xs

Prelude.filter definition:

filter _pred []    = []
filter pred (x:xs)
  | pred x         = x : filter pred xs
  | otherwise      = filter pred xs

If I run this:

map (==5) [1..]

The output starts and it never ends, until i stop it. Wich makes sense since the list is infinite.

But now if i run this:

filter (==5) [1..]

I see nothing, not even [5,. Which also makes sense since the list is infinite too, but i want to understand what's the difference beetwen map and filter that makes this. Thank you and sorry for my english!

Edit: I was using tryhaskell.org and that was the problem!

¿Fue útil?

Solución

As discovered in the comments, this is due to using Try Haskell. From experimentation, it appears that it will wait for the program to terminate, 3 seconds to elapse, or 1024 characters of output to be produced, before ending and sending you the result. Unfortunately, filter (==5) [1..] will only produce a measly two characters ([5), not meeting the 1024 character limit, and for some reason or another Try Haskell won't send [5 back to you. Running it in a real GHCi should work just fine.

Otros consejos

Its related to the buffer settings. When you compile it, the BufferMode of stdin and stdout is by default often set to LineBuffering, printing only on a newline, buffer overflow or manual flush.

GHCi's BufferMode is set to NoBuffering¹, which will print your result immediately.

In case of LineBuffering:

  • map (==5) [1..] prints its result, because its large output leads to lots of buffer overflows.
  • filter (==5) [1..] never fills the buffer or writes a newline. So its not printed.

¹ if possible. NoBuffering for stdin might not work on Windows cmd, when compiled with GHC.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top