Values with let and where
| let in an expression | |
| where under a function | |
| No assignment | |
| Scope and shadowing |
let in an expression
let introduces names for the expression that follows in. It is an expression, so it can sit anywhere a value can:
total = let price = 12
qty = 3
in price * qty -- 36
At the GHCi prompt the in part is optional, because the session keeps the binding for the next line. In a file it is required.
where under a function
A where clause attaches helper names to a function definition. The body reads top down, and the details sit below where they do not interrupt it:
area :: Double -> Double -> Double
area w h = w * h + trim
where
-- both names are visible in the body above
trim = 0.0
A helper used by several equations of the same function is written once in the where block, and every equation sees it.
No assignment
There is no statement that changes a value. A name is bound once, and the binding never changes. This code does not do what it looks like it does:
x = 1
x = 2 -- error: conflicting definitions of x
To get a new value, compute a new one and give it a new name. When a loop seems necessary, recursion or a fold replaces it, which is the subject of lesson 17.
Scope and shadowing
An inner binding may reuse an outer name. The inner one wins for the rest of its block, and the outer one is untouched outside:
x = 10
f = let x = 20 in x + 1 -- 21
g = x + 1 -- 11
Shadowing is legal but rarely kind to readers. Use it for short
intermediate values, not for renaming a parameter in the middle of a
long function.
Next:
Types and type signatures
Article author: Arthur Isaev