Haskell: Can I use a where clause after a block with bind operators (>>=)?

haskell, monads, syntax

Solution

As ephemient explains, you can't use `where` clauses the way you do.

The error happens because in this code:

main =
  return [1..10] >>= \list ->
  print list'
    where
      list' = reverse list

The `where`-clause is attached to the main function.

Here's that same function with more parentheses:

main = return [1..10] >>= (\list -> print list')
  where
    list' = reverse list

I think its fairly obvious why you get the "`out of scope`" error: The binding for `list` is deep inside the `main` expression, not something the `where` clause can reach.

What I usually do in this situation (and I've been bitten by the same thing a bunch of times). I simply introduce a function and pass the `list` as an argument.

main = do
  list <- return [1..10]
  let list' = f list
  print list'
  where
    f list = reverse list -- Consider renaming list,
                          -- or writing in point-free style

Of course, I imagine your actual code in the `f` function is a lot more that just `reverse` and that's why you want it inside a `where` clause, instead of an inline `let` binding. If the code inside the `f` function is very small, I'd just write it inside the `let` binding, and wouldn't go through the overhead of introducing a new function.

Problem

I have a very simple question. I'd like to use a where clause after a bloc of code that uses bind operators but I get a compilation error. Here is a simple example: ``` main = putStrLn "where clause test:" >> return [1..10] >>= \list -> print list' where list' = reverse list -- test1.hs:5:28: Not in scope: `list' ``` I can use a let clause for list' as in ``` main = putStrLn "where clause test:" >> return [1..10] >>= \list -> let list' = reverse list -- works of course in print list' ``` but I'd really like it if I could use a where clause... I also tried with do notation ``` main = do putStrLn "where clause test:" list <- return [1..10] print list' where list' = reverse list --test3.hs:5:30: Not in scope: `list' ``` Same problem. Can I use a where clause in these circumstances?

Original source