views:

206

answers:

4

Specs

GHC 6.12.1

Mac OS X 10.6.4 x64

MacBook Pro

Problem

I'm having trouble using let syntax. The following code refuses to compile:

module Main where

main = let x = 1
        y = 2
        z = 3
    in putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z

I tried tabbing in y = 2 and z = 3 even more. No dice.

(Undesirable) Solutions

The only way I've gotten the code to compile is either

  1. Replacing hard tabs with spaces.
  2. Replacing the let clause with a where clause.
+3  A: 

Indent each declaration in the let-block to the same degree. Also good form is to indent the 'in' and 'let' to the same level. Eg..

main = let x = 1
           y = 2
           z = 3
       in putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z
Don Stewart
How do I do this with hard tabs?
mcandre
Why do you want to use hard tabs? They're mildly okay in languages that don't use indentation for meaning, but they are just going to make your life difficult in languages like Haskell or Python. Like they are right now.
jrockway
Python handles hard tabs excellently. One time, I had trouble coding Python through a web SSH client because the client couldn't insert tabs. I use hard tabs because I hate having to forcibly reindent other people's code to my preferred indentation width. Hard tabs don't have that problem, since text editors can view hard tabs at any width.
mcandre
+4  A: 

Saizan on #haskell explains that the assignments in a let expression have to align, not let itself. As long as the assignments line up, it's okay to use hard tabs or soft tabs.

Correct code:

module Main where

main = let
        x = 1
        y = 2
        z = 3
    in putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z
mcandre
+5  A: 

You simply can't control indentation correctly with tabs because the size of a tab is undefined.

Therefore, don't use tabs in Haskell. They're evil.

Neil Bartlett
Or, for things that need to have a different level of indentation, use a new line. E.g., put `let` on one line and `x = 1` on the next. Then tabs are no problem.
Justice
Neil, I beg to differ (see my answer). A guy on #haskell was able to help me construct a compiling, hard-tabbed version. In fact, Justice's answer is correct.
mcandre
+1  A: 

If you insist on TAB characters in your source, the following compiles:

module Main where

main =
    let x = 1
        y = 2
        z = 3
    in putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z

where all leading whitespace is either one or two TABs, and the whitespace between let and x = 1 is also a TAB. Viewed in vi's list mode to make TABs and line-ends explicit:

module Main where$
$
main =$
^Ilet^Ix = 1$
^I^Iy = 2$
^I^Iz = 3$
^Iin putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z$

Your life will be much simpler and your code prettier if you switch to spaces.

Greg Bacon
Thanks. I don't think I want to remember to tab between let and x every time. Also, any code I post will likely cause errors since readers will assume that there's an ordinary space there.
mcandre
Hence why hard tabs makes your code harder to code and read!
adamse