2012-04-23 37 views
8

Tôi đang cố gắng đọc n dòng nội dung vào Danh sách chuỗi. Tôi đã thử một số biến thể của mã bên dưới, nhưng không có gì hiệu quả.Đọc n dòng vào [Chuỗi]

main = do 
    input <- getLine 
    inputs <- mapM getLine [1..read input] 
    print $ length input 

này ném các lỗi sau:

Couldn't match expected type `a0 -> IO b0' 
       with actual type `IO String' 
    In the first argument of `mapM', namely `getLine' 
    In a stmt of a 'do' block: inputs <- mapM getLine [1 .. read input] 
    In the expression: 
     do { input <- getLine; 
      inputs <- mapM getLine [1 .. read input]; 
      print $ length input } 

main = do 
    input <- getLine 
    let inputs = map getLine [1..read input] 
    print $ length input 

ném

Couldn't match expected type `a0 -> b0' 
       with actual type `IO String' 
    In the first argument of `map', namely `getLine' 
    In the expression: map getLine [1 .. read input] 
    In an equation for `inputs': inputs = map getLine [1 .. read input] 

Làm thế nào tôi có thể làm điều này?

+3

Bằng cách này, 'đầu vào <- mapM (const getLine) [1 .. đọc đầu vào]' thực hiện chính xác những gì bạn cần. Vấn đề là bạn cố gắng ánh xạ 'getLine' qua các số' [1 .. n] 'nhưng' getLine' không phải là một hàm. Bằng cách sử dụng 'const', bạn biến nó thành một hàm chỉ bỏ qua đối số đầu tiên của nó. – Vitus

+0

@Vitus xứng đáng là một câu trả lời khác, tôi sẽ +1 nó. – vikingsteve

Trả lời

42

Sử dụng replicateM từ Control.Monad:

main = do 
    input <- getLine 
    inputs <- replicateM (read input) getLine 
    print $ length inputs 

Với tinh thần cho một người đàn ông một con cá/dạy anh ta cách câu cá: Bạn có thể đã tìm thấy chính mình này bằng cách tìm kiếm Hoogle.

Bạn có:

  • một hành động để thực hiện các loại IO String
  • một số lần thực hiện hành động đó (loại Int)

Bạn muốn:

  • một hành động thuộc loại IO [String]

Vì vậy, bạn có thể search Hoogle for (IO String) -> Int -> (IO [String]). replicateM là lần truy cập đầu tiên.

0

Một cách khác bạn có thể thực hiện tác vụ này là sử dụng bản sao thuần túy và công cụ sequence :: (Traversable t, Monad m) => t (m a) -> m (t a) . Cho phép nói đầu tiên, chúng tôi sẽ yêu cầu đếm và sau đó yêu cầu nhiều số nguyên để in tổng của chúng trên thiết bị đầu cuối.

sumCountManyData :: IO() 
sumCountManyData = putStr "How many integers to sum..? " 
        >> getLine 
        >>= sequence . flip replicate getLine . read 
        >>= print . sum . map read 
Các vấn đề liên quan