18

I am a huge newbie to Haskell, I actually just started 10 minutes ago. I am trying to figure out how to define a variable inside a function. Lets say I have the function

foo :: Int -> Int
foo a = 
    b = a * 2
    b
-- Yes, I know, it doesn't do anything interesting

When I run it in GHCi I get a syntax error! How can you define a variable inside a function?

2

2 Answers 2

33

There are two ways to do this:

foo a = b where b = a * 2
foo a = let b = a * 2 in b

In most cases, the choice between them is an aesthetic rather than technical one. More precisely, where may only be attached to definitions, whereas let ... in ... may be used anywhere an expression is allowed. Both where and let introduce blocks, making multiple internal variables convenient in both cases.

Sign up to request clarification or add additional context in comments.

4 Comments

Hey I was wondering how you would define multiple helper variables inside a function, would you do something like where b = a * 2, c = a * 3 or would you use an entirely different "where" statement?
@EbenCowley A single where/let will do. Use ; to separate declarations on the same line, or read about the indentation rules to use multiple lines. (This is the meaning of the last sentence of my post.)
@DanielWagner : I am very new to haskell. so one basic question : does foo a = b where b = a * 2 basically translates to foo a=(/b->b)a * 2 ?
@rahulaga_dev That's a decent first approximation, but as always the truth is a bit more complicated. One difference of between lambdas and let/where blocks that's important here is that the former make their variable monomorphic and the latter don't. For example, foo :: (Int, Double); foo = (x, x) where x = 3 works fine, but foo :: (Int, Double); foo = (\x -> (x, x)) 3 does not.
3

Disregarding technical correctness, the answer is "sort of".

I think it's better to think of a variable as a function of zero arguments evaluating to a given value.

module Main where
import System.IO

foo :: Integer -> Integer
foo a =
  b where
    b = a * 2

main = do
  putStrLn $ show $ foo 10

6 Comments

It is not a function of zero arguments. Every function in Haskell takes precisely one argument.
For more on what Magnus said, see Conal Elliott's blog post "Everything is a function" in Haskell?.
@MagnusKronqvist: Would you mind providing a document giving the documentation for that?
Functions are the values that have arrow type. Some values do, some values don't. But if it doesn't have an arrow type it's not a function.
@PaulNathan haskell.org/haskellwiki/Currying - if you allow something informal. Also you can google "Haskell currying".
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.