Non-Strictness means reducing the program/expressions outside-in and sub-expressions may be discarded and bottoms may not be evaluated.
Stricness means evaluating the program from inside-out.
Laziness means evaluating an expression when it is needed. When the evaluation engine sees the expression for the first time, creates a thunk to compute the expression and a pointer to the thunk. When the expression is needed, its value is computed and the thunk is replaced by its result.
Non-stricness usually involves laziness, but not always. For example, a parallel evaluation engine that eagerly computes subexpressions but discards them when they are not needed.
Haskell is a non-strict language.
Haskell is not a pure lazy language.
For example, pattern-matching is strict by default (using the ~
operator you can make it lazy):
let (a,b) = p
f ~(a,b) = ...
case p of ~(a,b) -> ...
(\ ~(a,b) -> ... )