Qqwy
Qqwy

Reputation: 5629

How to read three consecutive integers from stdin in Haskell?

I want to read an input like 12 34 56 into three integers using Haskell.

For a single integer, one might use myInteger <- readLn. But for this case, I have not found any solution, except the one of first reading a line, then replacing all spaces with ,, (using something like:

spaceToCommas str =
  let repl ' ' = ','
      repl  c =   c
  in map repl str

) and then calling read '[' ++ str ++ ']' which feels very hackish. Also, it does not allow me to state that I want to read three integers, it will attempt to read any amount of integers from stdin.

There has to be a better way.

Note that I would like a solution that does not rely on external packages. Using e.g. Parsec is of course great, but this simple example should not require the use of a full-fledged Parser Combinator framework, right?

Upvotes: 3

Views: 1754

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476503

What about converting the string like:

convert :: Read a => String -> [a]
convert = map read . words

words splits the given string into a list of strings (the "words") and then we perform a read on every element using map.

and for instance use it like:

main = do
    line <- getLine
    let [a,b,c] = convert line :: [Int] in putStrLn (show (c,a,b))

or if you for instance want to read the first three elements and don't care about the rest (yes this apparently requires super-creativity skills):

main = do
    line <- getLine
    let (a:b:c:_) = convert line :: [Int] in putStrLn (show (c,a,b))

I here returned a tuple that is rotated one place to the right to show parsing is done.

Upvotes: 4

Related Questions