2012-04-10 19 views
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 है और मैं समझ नहीं क्यों यह पार्स करने में विफल करना चाहिए।

+1

ठीक है, यह काम करता है अगर मैं प्रत्येक 'कथन' के अंत में डॉक्स ब्लॉक और अर्धविरामों के लिए ब्रेसिज़ जोड़ता हूं - लेकिन क्या यह अनुशंसित समाधान है? (यह थोड़ा अन-कार्यात्मक लगता है: पी) – 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 

आप को बदल सकते हैं समकक्ष,

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

वाह ... धन्यवाद !! – agam

4

आप अपने डू-ब्लॉक में ओवर-इंडेंट लाइनें। इसके अलावा, -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 डाल और बाद के बयानों को लाइन करें)

संबंधित मुद्दे