2012-04-23 15 views
8

Ich versuche n Zeilen mit Inhalt in eine Liste von Strings zu lesen. Ich habe verschiedene Varianten des Codes unten versucht, aber nichts hat funktioniert.Lesen von n Zeilen in eine [Zeichenfolge]

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

Dies führt den folgenden Fehler:

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 } 

Und

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

wirft

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] 

Wie kann ich das tun?

+3

Übrigens, 'Eingänge <- mapM (const getLine) [1 .. Leseeingang]' macht genau das, was Sie brauchen. Das Problem ist, dass Sie 'getLine' über Zahlen' [1 .. n] 'abbilden, aber' getLine' ist keine Funktion. Mit 'const' verwandeln Sie es in eine Funktion, die nur das erste Argument ignoriert. – Vitus

+0

@Vitus, das als eine andere Antwort würdig ist, werde ich es +1. – vikingsteve

Antwort

42

Verwenden replicateM von Control.Monad:

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

Im Geist einem Mann einen Fisch von dem,/einen Mann unterrichten zu fischen: Sie dies selbst haben könnten Hoogle durch die Suche gefunden.

Sie haben:

  • eine Aktion vom Typ dieser Aktion (Typ Int)

Sie wollen durchführen IO String

  • einige Male auszuführen:

    • eine Aktion vom Typ IO [String]

    So konnte man search Hoogle for (IO String) -> Int -> (IO [String]). replicateM ist der erste Treffer.

  • 0

    Eine andere Möglichkeit, diese Aktion tun kann, ist durch die reine Wiederholung verwenden und das sequence :: (Traversable t, Monad m) => t (m a) -> m (t a) Werkzeug. Sagen wir zuerst, wir werden nach einer Zählung fragen und dann nach so vielen ganzen Zahlen fragen, um ihre Summe auf dem Terminal auszudrucken.

    sumCountManyData :: IO() 
    sumCountManyData = putStr "How many integers to sum..? " 
            >> getLine 
            >>= sequence . flip replicate getLine . read 
            >>= print . sum . map read 
    
    Verwandte Themen