Note that there are some explanatory texts on larger screens.

plurals
  1. POHaskell: Where vs. Let
    primarykey
    data
    text
    <p>I am new to Haskell and I am very confused by <strong>Where</strong> vs. <strong>Let</strong>. They both seem to provide a similar purpose. I have read a few comparisons between <strong>Where</strong> vs. <strong>Let</strong> but I am having trouble discerning when to use each. Could someone please provide some context or perhaps a few examples that demonstrate when to use one over the other?</p> <blockquote> <p>Where vs. Let </p> <p>A <code>where</code> clause can only be defined at the level of a function definition. Usually, that is identical to the scope of <code>let</code> definition. <em>The only difference is when guards are being used</em>. The scope of the <code>where</code> clause extends over all guards. In contrast, the scope of a <code>let</code> expression is only the current function clause and guard, if any.</p> </blockquote> <p><a href="http://cheatsheet.codeslower.com/CheatSheet.pdf" rel="noreferrer">Haskell Cheat Sheet</a></p> <p>The <a href="http://www.haskell.org/haskellwiki/Let_vs._Where" rel="noreferrer">Haskell Wiki</a> is very detailed and provides various cases but it uses hypothetical examples. I find its explanations too brief for a beginner.</p> <p><strong>Advantages of Let</strong>:</p> <pre><code>f :: State s a f = State $ \x -&gt; y where y = ... x ... </code></pre> <p><a href="http://www.haskell.org/haskellwiki/State_Monad" rel="noreferrer">Control.Monad.State</a></p> <blockquote> <p>will not work, because where refers to the pattern matching f =, where no x is in scope. In contrast, if you had started with let, then you wouldn't have trouble.</p> </blockquote> <p><a href="http://www.haskell.org/haskellwiki/Let_vs._Where#Advantages_of_let" rel="noreferrer">Haskell Wiki on Advantages of Let</a></p> <pre><code>f :: State s a f = State $ \x -&gt; let y = ... x ... in y </code></pre> <p><strong>Advantages of Where</strong>:</p> <pre><code>f x | cond1 x = a | cond2 x = g a | otherwise = f (h x a) where a = w x f x = let a = w x in case () of _ | cond1 x = a | cond2 x = g a | otherwise = f (h x a) </code></pre> <p><a href="http://www.haskell.org/haskellwiki/Declaration_vs._expression_style" rel="noreferrer"><strong>Declaration vs. Expression</strong></a></p> <p>The Haskell wiki mentions that the <strong>Where</strong> clause is declarative while the <strong>Let</strong> expression is expressive. Aside from style how do they perform differently?</p> <pre><code>Declaration style | Expression-style --------------------------------------+--------------------------------------------- where clause | let expression arguments LHS: f x = x*x | Lambda abstraction: f = \x -&gt; x*x Pattern matching: f [] = 0 | case expression: f xs = case xs of [] -&gt; 0 Guards: f [x] | x&gt;0 = 'a' | if expression: f [x] = if x&gt;0 then 'a' else ... </code></pre> <ol> <li>In the first example why is the <strong>Let</strong> in scope but <strong>Where</strong> is not?</li> <li>Is it possible to apply <strong>Where</strong> to the first example?</li> <li>Can some apply this to real examples where the variables represent actual expressions?</li> <li>Is there a general rule of thumb to follow when to use each? </li> </ol> <hr> <h2>Update</h2> <p>For those that come by this thread later on I found the best explanation to be found here: "<a href="http://www.cse.iitb.ac.in/~as/fpcourse/haskell98_tutorial/patterns.html" rel="noreferrer">A Gentle Introduction to Haskell</a>".</p> <blockquote> <p>Let Expressions.</p> <p>Haskell's let expressions are useful whenever a nested set of bindings is required. As a simple example, consider:</p> <pre><code>let y = a*b f x = (x+y)/y in f c + f d </code></pre> <p>The set of bindings created by a let expression is mutually recursive, and pattern bindings are treated as lazy patterns (i.e. they carry an implicit ~). The only kind of declarations permitted are type signatures, function bindings, and pattern bindings. </p> <p>Where Clauses.</p> <p>Sometimes it is convenient to scope bindings over several guarded equations, which requires a where clause:</p> <pre><code>f x y | y&gt;z = ... | y==z = ... | y&lt;z = ... where z = x*x </code></pre> <p>Note that this cannot be done with a let expression, which only scopes over the expression which it encloses. A where clause is only allowed at the top level of a set of equations or case expression. The same properties and constraints on bindings in let expressions apply to those in where clauses. These two forms of nested scope seem very similar, but remember that a let expression is an expression, whereas a where clause is not -- it is part of the syntax of function declarations and case expressions.</p> </blockquote>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload