Send Beginners mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1.  seq vs deepseq (Ryan Warner)
   2. Re:  seq vs deepseq (Bob Ippolito)


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

Message: 1
Date: Tue, 21 Jul 2015 21:29:57 -0500
From: Ryan Warner <[email protected]>
To: [email protected]
Subject: [Haskell-beginners] seq vs deepseq
Message-ID:
        <CAMV_cL2XyLR=90_jiwtb1szxp_7ptjdvas3ydg1gnnfrjuw...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

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?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20150721/2bf7f6f8/attachment-0001.html>

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

Message: 2
Date: Tue, 21 Jul 2015 19:59:35 -0700
From: Bob Ippolito <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] seq vs deepseq
Message-ID:
        <CACwMPm_8w=Vw_3ON9qm+HQBG5CQ_80S0Sr5f-=ap56ijvkm...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

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:

*
http://chimera.labs.oreilly.com/books/1230000000929/ch02.html#sec_par-eval-whnf
* https://hackhands.com/lazy-evaluation-works-haskell/


On Tue, Jul 21, 2015 at 7:29 PM, Ryan Warner <
[email protected]> 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
> [email protected]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20150721/2b39fbd2/attachment-0001.html>

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

Subject: Digest Footer

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


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

End of Beginners Digest, Vol 85, Issue 13
*****************************************

Reply via email to