Let vs. Where
From HaskellWiki
(Difference between revisions)
(Improved layout) 

(9 intermediate revisions by 7 users not shown) 
Revision as of 06:11, 24 October 2012
Haskell programmers often wonder whether to uselet
where
This seems to be only a matter of taste in the sense of "Declaration vs. expression style", however there is more to it.
It is important to know thatlet ... in ...
where
Contents 
1 Advantages of let
Suppose you have the function
f :: s > (a,s) f x = y where y = ... x ...
Control.Monad.State
However, transforming to
f :: State s a f = State $ \x > y where y = ... x ...
where
f =
x
let
f :: s > (a,s) f x = let y = ... x ... in y
This is easily transformed to:
f :: State s a f = State $ \x > let y = ... x ... in y
2 Advantages of where
Because "where" blocks are bound to a syntactic construct, they can be used to share bindings between parts of a function that are not syntactically expressions. For example:
f x  cond1 x = a  cond2 x = g a  otherwise = f (h x a) where a = w x
case
f x = let a = w x in case () of _  cond1 x > a  cond2 x > g a  otherwise > f (h x a)
or a functional equivalent:
f x = let a = w x in select (f (h x a)) [(cond1 x, a), (cond2 x, g a)]
or a series of ifthenelse expressions:
f x = let a = w x in if cond1 x then a else if cond2 x then g a else f (h x a)
where
3 Lambda Lifting
One other approach to consider is that let or where can often be implemented using lambda lifting and let floating, incurring at least the cost of introducing a new name. The above example:
f x  cond1 x = a  cond2 x = g a  otherwise = f (h x a) where a = w x
could be implemented as:
f x = f' (w x) x f' a x  cond1 x = a  cond2 x = g a  otherwise = f (h x a)
let
where
4 Problems with where
If you run both
fib = (map fib' [0 ..] !!) where fib' 0 = 0 fib' 1 = 1 fib' n = fib (n  1) + fib (n  2)
and
fib x = map fib' [0 ..] !! x where fib' 0 = 0 fib' 1 = 1 fib' n = fib (n  1) + fib (n  2)
fib
let
Compare
fib = let fib' 0 = 0 fib' 1 = 1 fib' n = fib (n  1) + fib (n  2) in (map fib' [0 ..] !!)
and
fib x = let fib' 0 = 0 fib' 1 = 1 fib' n = fib (n  1) + fib (n  2) in map fib' [0 ..] !! x
fib'
x
In contrast to that, in the first case
fib'
where
x
 HaskellCafe on Etaexpansion destroys memoization?