2012-04-10 24 views
5

Một ví dụ đồ chơi nhưng vẫn bực bội:Haskell ném một lỗi phân tích cú pháp ở một nơi xa lạ

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 nói với tôi rằng tôi có một Parse error in pattern: putStrLn và tôi không thể tìm ra lý do tại sao nó nên không phân tích.

+1

Ok, điều này làm việc nếu tôi thêm niềng răng cho các khối và dấu chấm phẩy ở cuối mỗi 'tuyên bố' - nhưng đó là giải pháp được đề xuất? (có vẻ như một chút không hoạt động: P) – agam

+0

Bạn có thể giả vờ rằng dấu chấm phẩy và niềng răng đã ở đó, nhưng vô hình. (Có những quy tắc cho nơi mà các dấu ngoặc và dấu chấm phẩy tự động đi.) –

Trả lời

10

Sửa chữa:

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 

Khắc phục: Các dòng bên trong một khối do sẽ xếp hàng.

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

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

Fix 2: Khi sử dụng let bên trong một khối do, không sử dụng in.

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

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

Fix 3: Sử dụngforM_ (mà trả (), còn được gọi là void) thay vì forM (mà trả về một danh sách).

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

Vì vậy forM_ thể (hầu như) được viết như thế này:

forM_ xs f = do forM xs f 
       return() 

Thay đổi nhỏ: Bạn không cần return đây:

do func1 
    x <- func2 
    return x 

Bạn có thể thay đổi nó để tương đương,

do func1 
    func2 -- value of func2 is returned 
+0

Wow ... cảm ơn !! – agam

4

Bạn đã thụt lề đường trong các khối công việc của mình. Hơn nữa, bạn không cần một câu hỏi in cho các câu hỏi let trong do -blocks.

này làm việc cho tôi:

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) 

Bạn cũng có thể cấu trúc nó như thế này:

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 

(cho phép bạn tránh được những dấu ngoặc đơn; cách khác, đặt do vào cuối của \num -> và xếp hàng các câu sau)

Các vấn đề liên quan