Haskell在一个陌生的地方抛出一个解析错误

aga*_*gam 5 haskell parse-error

一个玩具的例子,但仍令人沮丧:

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)
Run Code Online (Sandbox Code Playgroud)

ghci告诉我,我有一个Parse error in pattern: putStrLn,我无法弄清楚为什么它不能解析.

Die*_*Epp 10

更正:

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
Run Code Online (Sandbox Code Playgroud)

修复:do块内的线应排成一行.

-- wrong
a = do codes <- something
        let numberCodes = zip [1..4] codes

-- right
a = do codes <- something
       let numberCodes = zip [1..4] codes
Run Code Online (Sandbox Code Playgroud)

修复2:在块let内使用时do,请勿使用in.

-- wrong
func = do
    let x = 17
    in print x

-- right
func = do
    let x = 17
    print x
Run Code Online (Sandbox Code Playgroud)

修复3:使用forM_(返回(),也称为void)而不是forM(返回列表).

codes <- forM [1..4] func...  -- returns a list
forM_ numberCodes $ ...       -- discards list, returns () 
Run Code Online (Sandbox Code Playgroud)

所以forM_(几乎)可以像这样写:

forM_ xs f = do forM xs f
                return ()
Run Code Online (Sandbox Code Playgroud)

小改动:你不需要return这里:

do func1
   x <- func2
   return x
Run Code Online (Sandbox Code Playgroud)

您可以将其更改为等效的,

do func1
   func2 -- value of func2 is returned
Run Code Online (Sandbox Code Playgroud)