Search code examples
haskelllet

Why do you need let keyword in do block?


What is the reason for having let in do block.

-- codeblock A
main = do
  let a = 0
  let f a = a + 1
  let b = f 0
  print (a,b)

-- codeblock B
main = do
  a = 0
  f a = a + 1
  b = f 0
  print (a,b)

Assume all let without in must followed by = (Is this true?)

Compiler should be able to imply let from = and preprocess/de-sugar codeblock B to codeblock A

using let in this case seem to be unnecessary, like you could write codeblock C but choose to write codeblock D

-- codeblock C
main = do
  print (a,b)

a = 0
f a = a + 1
b = f 0

-- codeblock D
main = do
  print (a,b)

function  a = 0
function  f a = a + 1
function  b = f 0

To clarify the my assumption doesn't not include let that followed by in which should leave untouched.

-- codeblock E
main = do
  a = 0
  f a = a + 1
  b = f 0
  c = let d = 1 
          e = 1
      in d + e
  print (a,b,c)

Solution

  • I don't know why it was done, but here is one reason I can imagine: it allows you to specify which bindings should be established sequentially, and which simultaneously, which can matter in the case of shadowing.

    For example, imagine that your suggestion is implemented, and then consider:

    foo :: [Int]
    foo = do
      x <- return [1]
      y = 0:x
      x = [1..5]
      y
    

    There are two reasonable ways to desugar this:

    foo1 :: [Int]
    foo1 = do
      x <- return [1]
      let y = 0:x
      let x = [1..5]
      y
    
    foo2 :: [Int]
    foo2 = do
      x <- return [1]
      let y = 0:x
          x = [1..5]
      y
    

    foo1 evaluates to [0,1], and foo2 to [0,1,2,3,4,5]. This is a strange way to write your code, surely, but the fact that the let is required to be explicit means there is no ambiguity as to what you intend.

    As noted in the comments by chi, shadowing is not the only reason you might need to be explicit about how your let bindings are grouped: a function definition might require multiple equations, to match multiple parameter patterns.