[Haskell-cafe] Let it be

Ross Mellgren rmm-haskell at z.odi.ac
Thu Oct 8 11:51:05 EDT 2009


You're running into this problem because you're in a do-block. In a do- 
block, all the continuing lines of a single statement in the do-block  
must be indented w/r/t to the first line. The cylinder example doesn't  
have this issue because it's not in a do-block.

The layout rule (I'm summarizing and I haven't read the spec, so  
someone jump on me if I'm stating the wrong thing) basically says that  
within some implied { }, ;'s will be inserted for any line that is at  
the same indentation level as the previous line, e.g.

import System.Random
main = do
   gen <- getStdGen
   let (randNumber, newGen) = randomR (1,6) gen :: (Int, StdGen)
   in putStrLn $ "Number is " ++ show randNumber

has the following implied symbols

import System.Random
main = do {
   gen <- getStdGen
; let (randNumber, newGen) = randomR (1,6) gen :: (Int, StdGen)
; in putStrLn $ "Number is " ++ show randNumber
}

which is now obviously wrong, as the let and in are in two separate  
statements.


Conversely,

import System.Random
main = do
   gen <- getStdGen
   let (randNumber, newGen) = randomR (1,6) gen :: (Int, StdGen)
     in putStrLn $ "Number is " ++ show randNumber

implied:

import System.Random
main = do {
   gen <- getStdGen
; let (randNumber, newGen) = randomR (1,6) gen :: (Int, StdGen)
     in putStrLn $ "Number is " ++ show randNumber
}

Hope that clarifies things.

-Ross



On Oct 8, 2009, at 11:43 AM, michael rice wrote:

> From Learn You a Haskell ("Let it be" section):
>
>    1. cylinder :: (RealFloat a) => a -> a -> a
>    2. cylinder r h =
>    3.     let sideArea = 2 * pi * r * h
>    4.         topArea = pi * r ^2
>    5.     in  sideArea + 2 * topArea
> ===================
>
> What's the proper indentation for LET so these problems (below)  
> don't arise? I thought LET and IN should be aligned in the same  
> column. Also, isn't a LET expression an "expression."
>
> Michael
>
> ==============
>
> This works:
>
> import System.Random
> main = do
>   gen <- getStdGen
>   let (randNumber, newGen) = randomR (1,6) gen :: (Int, StdGen)
>     in putStrLn $ "Number is " ++ show randNumber
>
> ==============
>
> This works:
>
> import System.Random
> main = do
>   gen <- getStdGen
>   let (randNumber, newGen) = randomR (1,6) gen :: (Int, StdGen)
>   putStrLn $ "Number is " ++ show randNumber
>
> ==============
>
> This doesn't:
>
> import System.Random
> main = do
>   gen <- getStdGen
>   let (randNumber, newGen) = randomR (1,6) gen :: (Int, StdGen)
>   in putStrLn $ "Number is " ++ show randNumber
>
> [michael at localhost ~]$ runhaskell zz.hs
>
> zz.hs:4:2:
>     The last statement in a 'do' construct must be an expression
>
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe



More information about the Haskell-Cafe mailing list