Lazy Evaluation



Short-circuit evaluation of boolean expressions:



in C: hardwired into the language
if (x && y)


In Haskell:
(&&), (||) :: Bool -> Bool -> Bool

True && y = y
_   && _ = False

False || y = y
_   && _ = True


--will this throw an error?
= undefined && undefined

--no. undefined never gets evaluated. it just shoves undefined into x

False && undefined
--outputs:
False
--because since the first arg is false, second never gets evaluated

True && undefined

--error, because since the first arg is true, it tries to eval the second


Evaluation happens as late as possible every time.

squareMax :: [Int] -> Maybe Int
squareMax xs | null xs = Nothing
             | otherwise = Just (m * m)
    where
        m = maximum xs


What drives evaluation?



Evaluation is driven by patterm matching.
-Variabels and _ always match; no need to evalluate the argument
- Specific value will need to be evaluated
-- :sprint will print how much of an expression has been evaluated so far
xs = [1..40:: [Int]
:sprint xs
--outputs _ (nothing evaluated)


When the pattern involves a data constructor, the argument is evaluated just enough to reveal its data constructor. This is called weak head normal form.

Infinite Data Structures:



first100Ints = [1 .. 100]
allIntegers = [1 ..]
--defining infinite lists in instantaenous because it doesnt involve evaluation
--you can even use subsets of infinite lists and thats fine
--you can also try to print an infinite list but obviously that will never terminate.

--numbering characters in a string
numberChars :: String -> [(IntChar)]
numberChars s = zip [1 .. n] s
    where
        n = length s
-- with infinite data structs:
numberChars :: String -> [(IntChar)]
numberChars s = zip [1 ..] s






Index