0

Why can't you use substitution inside a do block? This code works fine.

test :: (x -> x) -> [x] -> [x]
test f a = map f a
main :: IO ()
main = do
  let sq x = x * x :: Int
  let ret = test sq [1,2,3]
  print ret

But if you remove the let's inside the do block, I got compile errors.

parse error on input ‘=’
Perhaps you need a 'let' in a 'do' block?
e.g. 'let x = 5' instead of 'x = 5'

Is "let x = y" equivalent to "x <- y" inside a do block? So if the right hand side returns a IO something, you need to use let's (or <-) ? I know it's a dummy question but I always get compile error with this. eii

Jihyun
  • 883
  • 5
  • 17
  • 1
    [About `let =` vs `<-`](http://stackoverflow.com/questions/28624408/equal-vs-left-arrow-symbols-in-haskell/28625714#28625714) – chi Oct 07 '16 at 13:53
  • No, they are not the same. Consider `do` / `let p = putStrLn "hello world"` / `p` / `p` (imagine each / is a line break with appropriate indentation) – user253751 Oct 07 '16 at 21:20

1 Answers1

5

let is how you assign a value to a name inside a do block. let x = y is not equivalent to x <- y. Inside a do block, let desugars like this.

do let x = y
   ...

becomes

let x = y
in do ...

whereas

do x <- y
   ...

becomes

do y >>= (\x -> ...)

Bare = is only for top-level assignments, for defining functions and constants (which are a lot like 0-argument functions).

chepner
  • 497,756
  • 71
  • 530
  • 681