seq vs deepseq

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

seq vs deepseq

Ryan Warner
I'm trying to grok Haskell's laziness. In this example, why does the seq not force youTyped to wait for s to be fully evaluated, before returning a result to putStrLn?

--------------------
import System.IO (hSetBuffering,stdin,BufferMode(..))

youTyped :: String -> String
youTyped s = s `seq` "you typed: " ++ s

main = do
hSetBuffering stdin NoBuffering
s <- getContents
let l = map youTyped $ lines $ takeWhile ( /= '\04' ) s
mapM_ putStrLn ("Start Typing (Ctrl-D to exit):":l)
--------------------

The output looks like:

--------------------

$ runhaskell seqLazy.hs 

Start Typing (Ctrl-D to exit):

Hyou typed: Heelllloo  wwoorrlldd


fyou typed: faaiill


^D

--------------------

Changing seq, to deepseq does the trick though.

--------------------
import System.IO (hSetBuffering,stdin,BufferMode(..))
import Control.DeepSeq

youTyped :: String -> String
youTyped s = s `deepseq` "you typed: " ++ s

main = do
hSetBuffering stdin NoBuffering
s <- getContents
let l = map youTyped $ lines $ takeWhile ( /= '\04' ) s
mapM_ putStrLn ("Start Typing (Ctrl-D to exit):":l)
--------------------

Output:


$ runhaskell deepSeqLazy.hs 

Start Typing (Ctrl-D to exit):

Hello world

you typed: Hello world

success

you typed: success

^D


When does it make sense to use seq then?


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: seq vs deepseq

Bob Ippolito
seq forces the term into weak-head normal form. Basically just enough to tell whether the list is `[]` or not. It's the same kind of evaluation that would happen if you pattern matched on the constructor. Only one Char needs to be read in order to make that determination. Sometimes this is desirable, but other times you want to traverse the whole structure and make sure everything is forced. The confusion is made much worse because you're using lazy IO.

The `takeWhile (/= '\04')` is redundant here, the ^D never ends up in that string.

Most cases where you use `seq` rather than `deepseq` are because you know that the substructure is already evaluated, or there is no need to evaluate it, and it may be very inefficient to do that redundant work.

See also:



On Tue, Jul 21, 2015 at 7:29 PM, Ryan Warner <[hidden email]> wrote:
I'm trying to grok Haskell's laziness. In this example, why does the seq not force youTyped to wait for s to be fully evaluated, before returning a result to putStrLn?

--------------------
import System.IO (hSetBuffering,stdin,BufferMode(..))

youTyped :: String -> String
youTyped s = s `seq` "you typed: " ++ s

main = do
hSetBuffering stdin NoBuffering
s <- getContents
let l = map youTyped $ lines $ takeWhile ( /= '\04' ) s
mapM_ putStrLn ("Start Typing (Ctrl-D to exit):":l)
--------------------

The output looks like:

--------------------

$ runhaskell seqLazy.hs 

Start Typing (Ctrl-D to exit):

Hyou typed: Heelllloo  wwoorrlldd


fyou typed: faaiill


^D

--------------------

Changing seq, to deepseq does the trick though.

--------------------
import System.IO (hSetBuffering,stdin,BufferMode(..))
import Control.DeepSeq

youTyped :: String -> String
youTyped s = s `deepseq` "you typed: " ++ s

main = do
hSetBuffering stdin NoBuffering
s <- getContents
let l = map youTyped $ lines $ takeWhile ( /= '\04' ) s
mapM_ putStrLn ("Start Typing (Ctrl-D to exit):":l)
--------------------

Output:


$ runhaskell deepSeqLazy.hs 

Start Typing (Ctrl-D to exit):

Hello world

you typed: Hello world

success

you typed: success

^D


When does it make sense to use seq then?


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners



_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners