I find I quite seldom come across situations where I need to use the where
clause. However, I do find that I have used it very occasionally in the past. When is the where
clause used (i.e. what situations is it used in)? Under what circumstances should I use it?

- 137,316
- 36
- 365
- 468

- 7,893
- 10
- 37
- 45
-
3Use `where` where appropriate. – Tarrasch May 17 '11 at 14:29
-
2you might find some useful information in this related question: [where vs. let](http://stackoverflow.com/questions/4362328/haskell-where-vs-let) – Thies Heidecke May 17 '11 at 14:30
-
thanks @ Thies Heidecke that didn't even come up! – maclunian May 17 '11 at 14:35
6 Answers
There are two excellent answers to this question available on the Haskell Wiki as well:
http://haskell.org/haskellwiki/Declaration_vs._expression_style http://haskell.org/haskellwiki/Let_vs._Where
Both are used to create local definitions that perhaps make use of values passed into the scope of their enclosing function, and certainly are not available outside of the context of the enclosing function. They promote code reuse and minimize duplication. Given fix
and lambda, both can be desugared away entirely. Generally, I use where clauses whenever possible, and only tend to use let clauses for definitions inside a lambda or case block, or in do
notation, when making use of values extracted through <-
on previous lines. In general, I think declarative style is now much more prevalant than expression style in idiomatic modern Haskell code.

- 2,497
- 1
- 23
- 25

- 38,665
- 7
- 99
- 204
One concrete example where I've found it important - a function returning a recursively defined array.
lucas :: (Integral a) => a -> Array a
lucas n = a where
a = array (0,n) ((0,2):(1,1):[(i,a!!(i-1) + a!!(i-2)) | i<-[1..n])])
For the Lucas numbers 1 thru n (Fibonacci would've just been too obvious =P )
The important point being that without the where clause the array wouldn't have a name from inside the function body and you could not recursively define.

- 16,398
- 7
- 29
- 37
It's mostly a matter of style. Even if they are not exactly equivalent it's not very often that you must use one or the other. Instead it's up to you, and what you think looks nicer.

- 22,884
- 5
- 56
- 93
My rule of thumb - if you are defining something at the top level of a function, use "where". If you are defining a helper function which has multiple clauses, definitely use "where". Everywhere else, just pick one!

- 7,851
- 2
- 39
- 74
In my experience, where
is more readable then let
, because it often reads eerily similar to English.
For example:
myFun x = aCoefficient * (10 ** anExponent)
where aCoefficient = 100 - x
anExponent = x - 2
In English, I'd describe this as "myFun of x is a coefficient times (10 to an exponent), where the coefficient is 100 minus x, and the exponent is x minus 2"

- 8,438
- 5
- 36
- 58
Two stylistic advantages of using where
:
It places the value of the thing you are defining close to its name (and type).
func x = part1 . part2 (something x) where part1 = ... part2 = ...
instead of
func x = let part1 = part2 = in part1 . part2 (something x)
It encourages writing code that can be read "newspaper style" where the important stuff comes first, and all the details come later. That way you can stop reading whenever you feel you don't need to know the rest of the details.
func x = highlevel1 . highlevel2 (x + 42) where highlevel1 = medium (...) highlevel2 = medium (...) medium = ...
I mostly use let
when the bindings themselves are more interesting than the expression, and they are short. For example when the binding is just to do a pattern match:
func x = let (MyData y _ _) = something in y
This looks better in my opinion than
func x = y
where (MyData y _ _) = something

- 138,522
- 17
- 304
- 385