5

おもちゃの例ですが、まだイライラします:

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解析に失敗する理由がわかりません。

4

2 に答える 2

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_ (リストを返す()) の代わりに (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
于 2012-04-10T08:19:01.650 に答える
4

do ブロックの行を過度にインデントします。inさらに、ブロック内のforletステートメントは必要ありません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 ->後続のステートメントを並べます)

于 2012-04-10T08:18:18.713 に答える