2012-04-10 10 views
5

奇妙な場所でパースエラーがスローされますが、それでもイライラ:Haskellはおもちゃの例

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を持っており、それが構文解析に失敗する理由を私は理解できないと言われます。

+1

doブロックとセミコロンの中括弧を各 'ステートメント'の末尾に追加すると、これはうまく動作しますが、推奨される解決策ですか? (少し機能していないようです:P) – agam

+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:doブロック内letを使用して、inを使用しないでください。

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

-- right 
func = do 
    let x = 17 
    print x 

修正3:(リストを返す)の代わりにforMの(()を返し、別名、無効)使用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 

あなたはそれを変更することができます等価、

+0

うわー...ありがとう!! – agam

4

あなたのdoブロックに行が上書きされています。さらに、do -blocksにletステートメントのinステートメントは必要ありません。

これは私の作品:

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 

、あるいは、\num ->の終わりにdoを置きます後続の明細書を整理してください)

関連する問題