[Haskell-beginners] seq vs deepseq

Bob Ippolito bob at redivi.com
Wed Jul 22 02:59:35 UTC 2015


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 <
ryan.warner.mn+haskell at gmail.com> 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
> Beginners at haskell.org
> 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.html>


More information about the Beginners mailing list