一个玩具示例,但仍然令人沮丧:
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
告诉我,我有一个Parse error in pattern: putStrLn
,我无法弄清楚为什么它无法解析。
答案 0 :(得分: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
修复: do
块内的行应排成一行。
-- wrong
a = do codes <- something
let numberCodes = zip [1..4] codes
-- right
a = do codes <- something
let numberCodes = zip [1..4] codes
修复2:在let
区块内使用do
时,请勿使用in
。
-- wrong
func = do
let x = 17
in print x
-- right
func = do
let x = 17
print x
修复3:使用forM_
(返回()
,a.k.a。void)而不是forM
(返回列表)。
codes <- forM [1..4] func... -- returns a list
forM_ numberCodes $ ... -- discards list, returns ()
所以forM_
可以(差不多)这样写:
forM_ xs f = do forM xs f
return ()
小改变:您不需要return
:
do func1
x <- func2
return x
您可以将其更改为等效的
do func1
func2 -- value of func2 is returned
答案 1 :(得分:4)
你在do-blocks中过度缩进行。此外,in
- let
中的do
语句不需要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
forM numberCodes (\(num,code) ->
putStrLn $ "Got code " ++ show code ++ " for " ++ show num)
。
这对我有用:
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
forM numberCodes $ \(num,code) ->
putStrLn $ "Got code " ++ show code ++ " for " ++ show num
你也可以像这样构建它:
do
(允许您避开括号;或者,将\num ->
放在{{1}}的末尾并排列后续语句