Haskell throws a parse error in a strange place
haskell, parse-error
Solution
Correction:
numberMapper:: IO ()
numberMapper = do
codes <- forM [1 .. 4] $ \num -> do
putStrLn $ "Enter a code for " ++ show num
getLine
let numberCodes = zip [1 .. 4] codes
forM_ numberCodes $ \(num,code) ->
putStrLn $ "Got code " ++ show code ++ " for " ++ show num
Fix: The lines inside a `do` block should line up.
-- wrong
a = do codes <- something
let numberCodes = zip [1..4] codes
-- right
a = do codes <- something
let numberCodes = zip [1..4] codes
Fix 2: When using `let` inside a `do` block, don't use `in`.
-- wrong
func = do
let x = 17
in print x
-- right
func = do
let x = 17
print x
Fix 3: Use `forM_` (which returns `()`, a.k.a. void) instead of `forM` (which returns a list).
codes <- forM [1..4] func... -- returns a list
forM_ numberCodes $ ... -- discards list, returns ()
So `forM_` could (almost) be written like this:
forM_ xs f = do forM xs f
return ()
Minor change: You don't need `return` here:
do func1
x <- func2
return x
You can change it to the equivalent,
do func1
func2 -- value of func2 is returned
Problem
A toy example but still frustrating: ``` numberMapper:: IO () numberMapper = do codes <- forM [1 .. 4] (\num -> do putStrLn $ "Enter a code for " ++ show num code <- getLine return code) let numberCodes = zip [1 .. 4] codes in forM numberCodes (\(num,code) -> putStrLn $ "Got code " ++ show code ++ " for " ++ show num) ``` `ghci` tells me I have a `Parse error in pattern: putStrLn` and I can't figure out why it should fail to parse.