[Haskell-cafe] Haskel let

Richard Eisenberg eir at cis.upenn.edu
Mon Apr 1 18:32:37 CEST 2013


It might just be easiest for me to explain than to find another resource:

"let" and "where" are both ways of creating local variables in a function. They serve similar purposes, and in most cases, it's your choice of which one to use. (Comparing to C++, the choice of let vs. where is not too far from the choice between while(…) { … } and do { … } while(…). There are differences, but they're more a matter of style than anything else.) Further complicating this, in Haskell, is that there are two forms of "let": one that appears with "do" notation and one that appears independent of "do". So, we will tackle the three forms ("let … in", "where", and "let" with "do") separately:

Normal "let":
In a function (which does not use "do"), you can use "let" to make local variables. The word "in" separates the local variable declaration from the part of your function where you want to use that variable. Loosely translating from Haskell to C++:

Haskell:
> let foo = bar in baz

C++:
> /* insert correct type here */ foo = bar;
> baz

In both languages, the variable foo is available while executing baz.

Haskell allows multiple variable declarations lumped together in one "let", for convenience. These variables do not have to have the same type.

> let foo1 = bar1
>     foo2 = bar2
> in
> baz

In this last example, the "let" declares both foo1 and foo2, and you can use these variables in baz (and in bar1 and bar2, if you really want). Note that here is a place where indentation matters -- foo2 has the same indentation level as foo1. The "in" can appear on the same line as the last variable declaration or not, at your choosing.

This form of "let" (the one outside of "do") *always* needs an "in".


"where":
At the end of a function clause definition (a function clause is one branch of a function that does argument pattern-matching), you can insert a "where" section to declare local variables in that clause.

> some_function x =
>   do_cool_thing a b
>   where
>     a = blah x
>     b = something_long_and_complicated

Here, a and b are available in the body of the function (and throughout the "where" clause). This would be equivalent to

> some_function x =
>   let a = blah x
>       b = something_long_and_complicated
>   in do_cool_thing a b

It's best to use descriptive variable names with "where", because it can be hard to read code that uses "where" and poor variable names, as the definitions of the variables comes after their use.

"where" can also be used in other contexts, but I don't want to over-complicate things here -- this is the most common place for "where".


"let" in "do":

Using "do" notation, you can use "let" much like a normal "let", but this "let" has no "in". The variables declared by the "let" scope over the remainder of the "do" block.

> some_fun x = do
>   c <- something_monadic x
>   let a = pure_function c
>   another_monadic_thing c a

Here, the variable "a" is available in the last line. Note that there is no "in". This form of "let" can also, declare multiple new variables, just like the other one. It still does not have "in".

I hope this all helps!
Richard

On Apr 1, 2013, at 11:16 AM, A Smith wrote:

> Hi
> I think I've mastered much of  functional programming with Haskell, or at least I can write programs which process as desired.
> However the existence of the "let" statement  evades me  apart from a quick way to define a function. Then there is the "in" and "where" parts. Its been suggested its to do with scope and is obvious. I think I need to understand it in a C/C++/Perl style of code to have a Eureka moment   when it will be obvious.
> Can someone refer me to something  which will assist me ?
> 
> Andrew _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20130401/a49235de/attachment.htm>


More information about the Haskell-Cafe mailing list