yomin
yomin

Reputation: 551

'let' and variables in Haskell

I'm a newbie in Haskell and I'm reading "Learn You a Haskell for Great Good!".

An expression that defines with a "name" and a "space", followed by "parameters" could be used as functions. Consider the following code:

doubleMe = 2

this code actually follows the rule above, so we could see it as a function. but it really seems like an assign operations in java or c++.

So, How to understand the variable in Haskell?

Upvotes: 2

Views: 5023

Answers (1)

Jon Purdy
Jon Purdy

Reputation: 54981

At the top level of a program, name = expression is a definition. It creates a variable, in the sense of a mathematical variable—just a name for some expression. It can be a definition of a value:

two :: Int
two = 2

Or a definition of a function:

twice :: Int -> Int
twice x = x * two

A definition refers to a function if its type has a function arrow ->.

In a do block or GHCi, let name = expression is a local definition.

main :: IO ()
main = do
  let greet name = "Hello, " ++ name ++ "!"
  putStrLn (greet "world")

Finally, there is another use of the let keyword: let name = expression1 in expression2. This creates a variable local to a single expression:

length (let x = "hello" in x ++ x)  ==  10

Be aware that let takes a block of bindings, so it’s subject to the layout rules like other layout keywords, such as do, where, of as in caseof, and so on:

main :: IO ()
main = do

  -- Bindings must be aligned past the start column.
  --  ↓
  let greeting name = "Hello, " ++ name ++ "!"
      parting name = "Goodbye, " ++ name ++ "!"

  putStrLn (greeting "world")
  putStrLn (parting "world")

 

length $ let x = "hello"
             y = "goodbye"
  in x ++ y

As with other layout keywords, can instead put a newline and a fixed amount of indentation after let, and then not worry about alignment:

main = do              -- ← newline+indent
  let                  -- ← newline+indent
    greeting name = …
    parting name = …
  …

 

length $ let
  x = "hello"
  y = "goodbye"
  in x ++ y

Or you can always include explicit curly braces and semicolons:

main :: IO ();
main = do {
  let {
    greeting name = "Hello, " ++ name ++ "!";
    parting name = "Goodbye, " ++ name ++ "!";
  };
  putStrLn (greeting "world");
  putStrLn (parting "world");
};
length $ let {
    x = "hello";
    y = "goodbye";
  } in x ++ y

Upvotes: 8

Related Questions