# [Haskell-cafe] What is the role of \$!?

Luke Palmer lrpalmer at gmail.com
Wed Nov 28 23:55:15 EST 2007

```On Nov 29, 2007 4:23 AM, PR Stanley <prstanley at ntlworld.com> wrote:
>         PRS: You would also get different results - e.g.
>         let a = 3, b = 7, c = 2
>         therefore 20 = strict ( ( (a+(b*c)) )
>         therefore 17 = non-strict ( (a+(b*c)) )
>
>                 or am I misunderstanding the concept?

Yes.  If the strict program does not error, then the strict program
and the lazy program will have the same results.

Numerics are not the best way to illustrate the difference, because
they are essentially strict in their semantics.

head [] = error "empty list"

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

head (map (+1) [1,2,3])  -- rewrite as...

Strictly would go like this:

head (map (+1) (1:2:3:[]))           -- evaluate map (+1) (1:2:3:[])
head ((1+1) : map (+1) (2:3:[]))     -- evaluate 1+1
head (2 : map (+1) (2:3:[]))         -- evaluate map (+1) (2:3:[])
head (2 : (2+1) : map (+1) (3:[]))   -- evaluate 2+1
head (2 : 3 : map (+1) (3:[]))       -- evaluate map (+1) (3:[])
head (2 : 3 : (3+1) : [])            -- evaluate 3+1
head (2 : 3 : 4 : [])                -- evaluate [] (nothing to do)
2

Lazily would go like this:

-- try to match map (+1) (1:2:3:[])
-- against x:xs, need to evaluate map
head ((1+1) : map (+1) (2:3:[]))
-- match (1+1):map (+1) (2:3:[]) against
-- x:xs succeeds, with x = (1+1)
(1+1)
-- evaluate (1+1)
2

Here I'm describing lazy evaluation rather than non-strict semantics,
but they're pretty closely related.

Luke
```